真实面经题目 · 原创解析

Redis 缓存雪崩、击穿和穿透分别是什么,如何解决?

缓存雪崩、击穿和穿透都是缓存失效后流量打到后端的风险,但触发条件不同:雪崩是大面积不可用,击穿是热点 key 瞬时失效,穿透是请求的数据本来就不存在。回答时要先分类,再分别给出限流、降级、互斥重建、空值缓存、布隆过滤器和 TTL 随机化等治理手段。

出现于:字节跳动 · 后端开发

60 秒回答模板

我会先区分三个概念。缓存雪崩是大量 key 在同一时间过期,或者缓存集群整体故障,导致本来应由缓存承接的流量同时打到数据库;解决上要做 TTL 随机化、热点数据永不过期或后台续期、多级缓存、缓存高可用、限流熔断和降级。缓存击穿是某个热点 key 过期的一瞬间,大量并发请求同时回源查询并重建缓存;解决上常用互斥锁、singleflight 请求合并、逻辑过期、后台刷新和短期本地缓存。缓存穿透是请求查询不存在的数据,缓存和数据库都没有,攻击或异常参数会持续绕过缓存;解决上可以做参数校验、空值缓存、布隆过滤器、黑名单和访问频控。三者的共同目标是保护数据库,但定位思路要看影响范围、key 是否热点、数据是否存在。

考点 一句话区分
难度 真实面经高频题
回答目标 讲清机制、边界和追问

深入解析

01

先按问题来源分类

这三个问题的相似点是缓存没有有效吸收请求,后端存储承受了原本不该承受的流量;不同点在于故障入口。雪崩关注一批 key 或缓存服务同时失效,击穿关注单个热点 key 失效,穿透关注请求目标本身不存在。面试时先把维度拆开,后面的方案才不会混在一起。

02

雪崩是大面积失效

雪崩常见于大量缓存使用相同 TTL、定时任务批量写入导致同时过期,或者缓存节点、网络、代理整体不可用。后果是数据库流量突然放大,连接池、慢查询和线程池会连锁恶化。治理重点是避免集中失效,并为缓存不可用准备降级链路,而不是只在数据库层扩容。

03

击穿是热点重建竞争

击穿的典型场景是商品详情、热榜、活动配置等热点 key 刚好过期,瞬时大量请求都发现缓存未命中,然后同时查询数据库并写缓存。它不是大面积 key 失效,而是热点被并发放大。解决核心是同一时刻只允许少量请求回源,其余请求等待、复用旧值或走短期兜底。

04

穿透是无效请求绕过

穿透常由非法 id、被删除资源、爬虫枚举、恶意攻击或上游脏数据造成。因为缓存没有这个 key,数据库也查不到,系统每次都重复走一次昂贵查询。治理要前置拦截明显无效参数,并把“确定不存在”的结果也纳入短期缓存,避免不存在的数据被反复打穿。

05

工程治理要组合使用

单一手段通常不够。TTL 随机化降低雪崩概率,互斥锁和请求合并控制击穿并发,空值缓存和布隆过滤器缓解穿透;同时还要有缓存集群高可用、超时设置、限流、熔断、监控告警和容量预案。高分回答会把预防、止损和恢复放在同一套链路里讲。

易错点

  • 把雪崩、击穿、穿透都说成缓存过期,没有区分大面积失效、热点失效和数据不存在。
  • 只给数据库扩容方案,忽略问题本质是缓存层防护和流量治理失效。
  • 给所有 key 设置相同过期时间,反而制造集中到期风险。
  • 使用互斥重建但没有超时、旧值兜底和失败处理,导致热点请求被锁放大。

面试官追问

空值缓存会带来什么副作用?

最大副作用是短时间内掩盖新写入的数据。例如某个 id 之前不存在,被缓存成空值后又创建成功,用户可能在空值 TTL 内仍读不到。解决方式是空值 TTL 设置较短,写入成功后主动删除空值缓存,并对核心链路走读己之写或强一致查询。

布隆过滤器为什么能防穿透?

布隆过滤器可以快速判断一个 id 是否一定不存在。若判断一定不存在,就不用访问缓存和数据库;若判断可能存在,再继续查询。它有误判率,但通常不会漏判已加入的数据,适合挡掉大量明显不存在的枚举请求。

互斥锁解决击穿时要注意什么?

要设置锁超时,避免重建请求异常导致长期阻塞;等待方不能无限等待,要有超时和旧值兜底;重建失败不能删除可用旧值;锁粒度应按 key 控制,避免一个热点 key 影响其他正常 key。

缓存服务整体故障时只靠 TTL 随机化有用吗?

没有用。TTL 随机化只解决集中到期,不能解决缓存集群不可用。整体故障需要高可用架构、连接池隔离、快速失败、限流降级、本地兜底和恢复后的预热,避免故障期间和恢复瞬间都冲击数据库。