Redis 缓存雪崩,缓存击穿,缓存穿透

缓存穿透:

查询一条不存在的缓存数据,每次穿过缓存直接查数据库,造成数据库压力过大。

解决办法:

  1. ‌布隆过滤器:可以判断一个元素是不是在一个集合里面,当查询一个数据时,布隆过滤器判断数据不存在,则不差数据库直接返回不存在
  2. 缓存空的结果,对查询失败的固定设置一个空的缓存结果并设置较短的过期时间

缓存击穿:

缓存中某个高频数据过期后 这个数据被大量请求访问,由于缓存失效导致数据请求同时穿透到数据库层,瞬间对数据库造成巨大压力
解决办法(避免大量线程同时访问数据库重新建立缓存数据):

  1. 设置互斥锁,缓存失效后不是立即查询数据库,而是通过互斥锁保证同一个时间内只有一个请求去查库并保存到缓存中,其他数据则在锁释放后从缓存中查询(可能会死锁,在等待释放时其他线程会消耗CPU,降低系统吞吐量)
  2. 永久缓存。对某些数据设置更长的过期时间,或者数据更新时同时更新缓存
  3. 使用定时任务刷新过期数据
  4. 不设置过期时间,设置单独字段代表过期时间,查询出来后判断当前字段时间过期,异步通知后台线程重新刷新缓存,当前线程直接返回过期数据

缓存雪崩:

同一时间大量的热点数据同时过期或者失效或者redis宕机,导致大量请求穿透到数据库,造成数据库压力过大
解决办法:

  1. 设置随机过期时间,为每个缓存对象设置一个随机过期时间,避免同时失效
  2. 使用锁或者队列,在高并发的情况下使用分布锁或者消息队列来控制数据库的访问,比如redis的分布式锁来控制对数据库的访问
  3. 使用高可用架构,通过主从架构,集群,哨兵模式,保证redis服务的高可用,避免单点故障
  4. 多级缓存,在redis和数据库之间加一个本地缓存,即使redis挂了请求也能命中本地缓存
  5. 服务降级和限流,数据库压力过大时可以拒绝部分请求,或者直接返回数据库中已经过期的缓存数据保证系统不挂掉

总结:

这三种为你通常需要结合多种策略来综合解决,比如可以使用过滤器预防穿透,设置互斥锁和随机过期时间来预防击穿和雪崩,此外还需要合理设计缓存策略和引入适当监控和预警机制

posted @ 2026-03-11 14:56  阿陌i  阅读(28)  评论(0)    收藏  举报