Skip to content

P12 使用 Redis 出现缓存击穿、雪崩、穿透怎么解决 ​

面试题:Redis 缓存的三大经典问题——击穿、雪崩、穿透是什么?怎么解决?

三个问题先分清 ​

问题定义典型表现
缓存穿透查询不存在的数据,缓存没有、DB 也没有,每次请求都打到 DB恶意攻击用不存在的 id 打爆 DB
缓存击穿缓存中某个热点 key 过期,瞬间大量请求同时打到 DB热点商品/热搜词过期的一瞬间
缓存雪崩大量 key 同时过期(或 Redis 宕机),请求全部打到 DB整批缓存设置了相同过期时间

解决方案 ​

缓存穿透 ​

  1. 缓存空值:查不到的数据也写缓存(value 为 null/空标记),设置较短过期时间;
  2. 布隆过滤器:请求前先判断 key 是否可能存在,不存在直接拒绝;
  3. 参数校验:非法 id(负数、超长、格式错误)直接拦截;
  4. 限流/风控:异常频次 IP 限流。

缓存击穿 ​

  1. 互斥锁:缓存失效时,只让一个线程去查 DB 回填,其他线程等待(Redis setnx 分布式锁 / JVM 锁):
text
查缓存 miss → 加锁(setnx)→ 再查一次缓存 → 仍 miss 才查 DB → 回填缓存 → 释放锁
  1. 逻辑过期:value 里存过期时间,后台异步刷新,不删除 key;
  2. 热点数据永不过期 + 后台任务定时更新。

缓存雪崩 ​

  1. 过期时间加随机值:如基础 TTL + 随机 0~300 秒,避免同时过期;
  2. 多级缓存:本地缓存(Caffeine)+ Redis,本地兜底;
  3. Redis 高可用:集群/主从 + 哨兵,避免单点宕机;
  4. 服务降级:缓存不可用时,对非核心接口降级返回,保护 DB;
  5. 限流 + 熔断:DB 压力过大时熔断,防止雪崩放大。

加分点 ​

  • 布隆过滤器有误判率,适合"不存在是常态"的场景(如黑名单、防穿透 id);
  • 互斥锁要注意防死锁(加过期时间)和防缓存击穿后的重复查询;
  • 雪崩不止 key 过期,Redis 宕机也会导致,所以要有降级预案。

一句话总结 ​

穿透用"缓存空值/布隆过滤器",击穿用"互斥锁/逻辑过期",雪崩用"过期时间随机化 + 多级缓存 + 高可用 + 降级",三个问题本质都是保护数据库不被瞬时流量打垮。

基于 VitePress 重建