目录
- 缓存穿透
- 解决方案
- 缓存空对象
- 布隆过滤器
- 缓存击穿
- 解决方案
- 对访问数据库的操作加锁
- 提前缓存热点数据,设置热点数据永不过期
- 缓存雪崩
- 解决方案
- Redis高可用
- 限流降级
- 数据预热
- 设置合理的过期时间
- 参考
缓存穿透
指的是对某个一定不存在的数据进行请求,该请求将会穿透缓存到达数据库。
如:用户查询一个 id = -1 的商品信息,一般数据库 id 值都是从 1 开始自增,很明显这条信息是不在数据库中,当没有信息返回时,会一直向数据库查询,给当前数据库的造成很大的访问压力。
解决方案
-
缓存空对象
缓存空对象是指一个请求发送过来,如果此时缓存中和数据库都不存在这个请求所要查询的相关信息,那么数据库就会返回一个空对象,并将这个空对象和请求关联起来存到缓存中,当下次还是这个请求过来的时候,这时缓存就会命中,就直接从缓存中返回这个空对象,这样可以减少访问数据库的压力,提高当前数据库的访问性能。
缺点:可能会缓存大量空对象,浪费内存,可以通过设置过期时间解决 -
布隆过滤器
布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量(位图)和一系列随机映射函数(哈希函数)。
布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
布隆过滤器详细介绍
使用流程:
(1)将数据库所有的数据加载到布隆过滤器
(2)查布隆过滤器(如果未命中直接结束)
(3)查Redis缓存数据(如果未命中查询数据库 )
(4)查询数据库
缓存击穿
缓存击穿是指有某个经常被查询的key在缓存过期后或一个未被缓存的key,突然接受到大量有关这个key的访问请求,这样会导致大并发请求直接穿透缓存,请求数据库,瞬间对数据库的访问压力增大。
缓存击穿的原因:
- 一个“冷门”(未缓存)的key,突然被大量用户请求访问。
- 一个“热门”key,在缓存中时间恰好过期,这时有大量用户来进行访问。
解决方案
-
对访问数据库的操作加锁
当key要查询数据库的时候加上一把锁,这时只能让第一个请求进行查询数据库,然后把从数据库中查询到的值存储到缓存中,对于剩下的相同的key,可以直接从缓存中获取即可。
- 单机环境下:使用Lock、Synchronized 加锁
- 分布式环境下使用分布式锁,如:基于数据库、基于Redis或者zookeeper 的分布式锁。
-
提前缓存热点数据,设置热点数据永不过期
缓存雪崩
缓存雪崩是指在某一个时间段内,缓存集中过期失效,如果这个时间段内有大量请求,而查询数据量巨大,所有的请求都会达到存储层,存储层的调用量会暴增,引起数据库压力过大甚至宕机。
缓存雪崩的原因:
- Redis宕机
- 大量热点数据同时过期
解决方案
-
Redis高可用
搭建Redis集群(哨兵模式),减少Redis宕机的可能 -
限流降级
在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量,对某个key只允许一个线程查询数据和写缓存,其他线程等待。 -
数据预热
在正式部署之前,先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。在即将发生大并发访问前手动触发加载缓存不同的key。 -
设置合理的过期时间
为了防止缓存在同一时间大面积过期导致的缓存雪崩,可以通过观察用户行为,合理设置缓存过期时间来实现;
参考
Redis的缓存了解吗?
Cyc2018