缓存击穿?
高并发情况下,某个热门key突然过期,导致大量请求在Redis未找到缓存数据,进而全部去数据库访问,引起 数据库压力瞬间增大。
解决:缓存击穿的情况下一般不容易造成DB的宕机,只是会造成对DB的周期性压力
1.Redis中的数据不设置过期时间,在缓存的对象上添加一个属性标识过期时间,每次获取到数据时,校验对象 中的过期时间属性,如果数据即将过期,则异步发起一个线程主动更新缓存中的数据,(可能会导致拿到过 期的值)
2.为热点数据设置为永不过期,然后加一个互斥锁保证缓存的单线程写
缓存穿透?
缓存穿透是指查询缓存和DB中都不存在的数据
解决:
1.利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间 重试
2.采用异步更新策略,无论key是否取到值,都直接返回
3.,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如 果不合法,则直接返回。
缓存雪崩?
同一时间大量的key过期,由于查询数据量巨大,引起DB压力过大甚至导致DB宕机
解决:
1.给缓存失效时间加上一个随机值,如果是集群,热点key均匀分布
2.设置热点数据永远不过期。
3.使用互斥锁,但是该方案吞吐量明显下降了。
4.双缓存:我们有两个缓存,缓存A和缓存B。缓存A的失效时间为20分钟,缓存B不设失效时间。
1.从缓存A读数据库,有则直接返回
2.A没有数据,直接从B读数据,直接返回,并且异步启动一个更新线程。
3.更新线程同时更新缓存A和缓存B。
Key的过期淘汰机制:可以对缓存数据设置过期时间,但是并非key过期时间到了就一定会被redis删除
定期删除:Redis默认是每隔100ms就随机删除一些过期的key
惰性删除:由于定期删除导致一些过期的没有删除,在用户从缓存获取数据时,redis检查这个key是否过期,过期就删除这个key(惰性删除就是在查询的时候将过期的key删除)
内存淘汰机制:
volatile-lru :从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。(推荐)
volatile-ttl :从已设置过期时间的数据集中挑选将要过期的数据淘汰
volatile-random :从已设置过期时间的数据集中任意选择数据淘汰。
allkeys-lru :当内存不足以容纳新写入数据时移除最近最少使用的key。
allkeys-random :从数据集中任意选择数据淘汰。
no-enviction(默认) :当内存不足以容纳新写入数据时,新写入操作会报错。