Redis击穿/穿透/雪崩/淘汰四种解决方案
不做标题党,只做好文章,“学无止境,前进不止”
缓存击穿
描述
我们的业务通常会有几个数据会被频繁地访问,比如秒杀活动,这类被频地访问的数据被称为热点数据。
如果缓存中的某个热点数据过期了,此时大量的请求访问了该热点数据,就无法从缓存中读取,直接访问数据库,数据库很容易就被高并发的请求冲垮,这就是缓存击穿的问题。
解决方案
- 永不过期
- 逻辑过期
- 服务降级
缓存穿透
描述
当发生缓存雪崩或击穿时,数据库中还是保存了应用要访问的数据,一旦缓存恢复相对应的数据,就可以减轻数据库的压力,而缓存穿透就不一样了。
当用户访问的数据,既不在缓存中,也不在数据库中,导致请求在访问缓存时,发现缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据,没办法构建缓存数据,来服务后续的请求。那么当有大量这样的请求到来时,数据库的压力骤增,这就是缓存穿透的问题。
解决方案
- 布隆过滤器
- 空值存储
- 互斥锁,不推荐
- 异步更新
- 服务降级
缓存雪崩
描述
通常我们为了保证缓存中的数据与数据库中的数据一致性,会给 Redis 里的数据设置过期时间,当缓存数据过期后,用户访问的数据如果不在缓存里,业务系统需要重新生成缓存,因此就会访问数据库,并将数据更新到 Redis 里,这样后续请求都可以直接命中缓存。
当大量缓存数据在同一时间过期(失效)或者 Redis 故障宕机时,如果此时有大量的用户请求,都无法在 Redis 中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃,这就是缓存雪崩的问题。
解决方案
- 随机失效时间
- 服务降级
- 互斥锁,不推荐
- 双缓存,用的不多
缓存淘汰
最大内存参数
我们的redis数据库的最大缓存、主键失效、淘汰机制等参数都是通过配置文件来配置的。这个文件是我们的redis.conf文件。
maxmemory :设置最大内存,比如: maxmemory 500mb
内存淘汰策略
截至目前redis一共为我们提供了八个不同的内存置换策略。很早之前提供了6种。
lru:最近最少使用,如果数据最近被访问过,那么将来被访问的几率也更高。
lfu:最不经常使用,如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小。
random:随机淘汰
ttl:即将过期
volatile-lru,针对设置了过期时间的key,使用lru算法进行淘汰。(最近最少淘汰)
allkeys-lru,针对所有key使用lru算法进行淘汰。(最近最少淘汰)
volatile-lfu,针对设置了过期时间的key,使用lfu算法进行淘汰。
allkeys-lfu,针对所有key使用lfu算法进行淘汰。
volatile-random,从所有设置了过期时间的key中使用随机淘汰的方式进行淘汰。
allkeys-random,针对所有的key使用随机淘汰机制进行淘汰。
volatile-ttl,删除生存时间最近的一个键。
noeviction,不删除键,值返回错误。
设置内存淘汰具体使用哪种策略:maxmemory-policy volatile-lru
淘汰机制的实现
既然是淘汰,那就需要把这些数据给删除,然后保存新的。
Redis删除策略主要有以下几种:
- 惰性删除
- 定时删除
- 主动删除