缓存雪崩
所谓缓存雪崩就是在某一个时刻,缓存集大量失效,所有流量直接打到数据库上,对数据库造成巨大的压力
场景
- 例如电商抢购平台的想象,一般就是比如12点开始,在一点的时候大量key失效,这个时候就会造成缓存雪崩的现象
解决方案
- 方案一:加锁/队列
- 加锁/队列;这样虽然能降低数据库压力,但是同时,响应也很慢
- 方案二:缓存标记
- 给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存
- 方案三:混存过期时间错开
缓存穿透
所谓缓存击穿的场景发生在故意攻击的场景下;比如说,本来查询意见商品的序号是正数,但是请求方总是请求大量的负数过来,导致缓存无效,全部流量都打到了数据库中,如果某一时刻流量过大,则会导致数据库崩溃
解决方案
- 方案一:布隆过滤器
- 布隆过滤器会判断某个元素是否在某个值中
- 方案二:缓存空值
- 可以把一些不符合要求的数据的key值设置为null,这样就不会一直去查数据库了但是需要设置过期时间
- 方案三:对参数进行校验,不合法参数进行拦截
- 方案四:设置频繁访问IP值拉黑
缓存击穿
-
说缓存击穿之前,我们先来了解一个概念——热点key,某个访问非常频繁,访问量非常大的一个缓存key,我们叫做热点key。
-
缓存击穿是指某个热点key在失效的瞬间(一般是缓存时间到期),持续的大并发请求穿破缓存,直接打到数据库,就像在一个屏障上凿开了一个洞,造成数据库压力瞬间增大,这就是缓存击穿。
解决方案
- 设置热点数据"永不过期"
- 加上互斥锁:上面的现象是多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它
- 其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后将数据放到redis缓存起来。后面的线程进来发现已经有缓存了,就直接走缓存
最后总结
- 雪崩是大面积的key缓存失效
- 穿透是redis不存在这个key
- 击穿是某一热点key突然失效,最终的受害者都是数据库