缓存雪崩
同一时间点 大面积key失效,导致后续的请求都落在数据库上,造成数据库短时间内承受大量请求
可能导致雪崩的场景:
- 缓存重启
- 第一次启动服务 缓存从还没有数据 会导致雪崩
解决方案:
- 过期时间 随机设置
- 给每一个缓存增加 相应的缓存标记,记录 缓存 是否失效,如果 缓存标记 失效了,则更新缓存数据。比较消耗性能,要一直监控缓存标记
- 缓存预热,启动应用之前,先把部分热点数据提前放到缓存中
- 互斥锁,在第一次判断缓存没有要查询数据库的时候,把 对应的缓存key 锁起来,限制统一时间只能有一个线程访问这个缓存key,其他线程要么返回失败,要么自旋等待。在查询完数据库之后将数据放入缓存,同时 释放这个 互斥锁,目的是避免短时间内大量操作 同一个key
缓存穿透
缓存 和 数据库中 都没有数据,请求还是会落在数据库中 通常这种场景来自于 网络攻击
解决方案:
- 业务接口层增加校验,ex:用户鉴权校验、id <=0校验
- 缓存 和 数据库中 都没有的数据,也可以在缓存存一个key-value=null的键值对,防止 针对某一个key的暴力工具
- 布隆过滤器,将 所有可能存在的数据 哈希到 一个足够大的 bitmap 中,一个一定不存在的数据 会被这个bitmap 过滤掉,避免了对底层存储系统的查询压力;但是存在的数据 不一定真的存在 bitmap中(待整理)
缓存击穿
缓存中没有、数据库中有(一般这种情况是缓存时间到期) 和雪崩不同的是,击穿 是指 并发查询同一条数据,雪崩是指很多不同数据都过期了
解决方案
- 设置 热点数据 永不过期
- 针对 这个同一条数据 增加互斥锁
|