什么是缓存雪崩?如何解决?
简化版
缓存雪崩指大量缓存 key 在同一时间失效,或者缓存集群整体不可用,导致原本被缓存挡住的请求突然全部打到数据库,把数据库压垮。解决思路是打散过期时间、提前预热热点数据、提升缓存高可用,并用限流、熔断、降级保护数据库。
详细版
缓存雪崩通常有两类原因:
| 原因 | 现象 | 主要方案 |
|---|---|---|
| 大量 key 同时过期 | 同一时刻大量请求回源 DB | TTL 加随机值、热点预热、后台刷新 |
| 缓存整体故障 | Redis 不可用,所有请求绕过缓存 | Redis 主从/哨兵/Cluster、多级缓存、熔断降级 |
雪崩和击穿、穿透要区分清楚:击穿是单个热点 key 失效,穿透是查不存在的数据,雪崩是大量 key 或整个缓存层同时失效。面试回答要强调:缓存雪崩不是只修 Redis,还要保护数据库,因为真正被打垮的通常是 DB 和上游线程池。
完整版教学
一、雪崩为什么危险
缓存的价值在于挡住绝大多数读流量。一个系统平时可能 99% 的商品详情、配置、用户信息都从 Redis 返回,数据库只承担少量未命中流量。一旦大量缓存同时失效,数据库要从承受 1% 流量突然变成承受 100% 流量,压力可能瞬间放大几十倍甚至上百倍。
危险还不止数据库。数据库变慢后,业务线程等待 DB 响应,线程池被占满,请求排队,网关超时,上游重试,重试又进一步放大流量。缓存雪崩很容易演变成服务雪崩。
二、第一类雪崩:大量 key 同时过期
这种常发生在批量预热或批量回填时。比如上线时把 10 万个商品都写入缓存,统一设置 30 分钟过期。30 分钟后,这批 key 几乎同时失效,用户请求同时回源数据库,DB 被冲垮。
最简单有效的做法是 TTL 加随机值。不要所有 key 都设置 30min,可以设置成 30min + random(0, 5min)。这样过期时间被摊开,回源请求也被摊开。热点 key 还可以做后台续期或逻辑过期,让缓存刷新从用户请求路径转移到后台任务。
三、第二类雪崩:缓存服务整体故障
如果 Redis 主节点挂了、网络隔离、集群不可用,就不是某些 key 过期,而是整个缓存层失效。应对这类问题,要靠高可用架构:Redis 主从复制、哨兵自动故障转移、Redis Cluster 分片,尽量避免单点故障。
还可以加多级缓存。应用本地缓存放一小部分热点数据,Redis 不可用时,本地缓存至少能挡住最热的一批请求,为 Redis 恢复争取时间。但本地缓存一致性更弱,只适合能容忍短暂旧值的数据。
四、数据库保护是最后防线
即使做了随机 TTL 和 Redis 高可用,也不能假设雪崩永远不会发生。最后一定要保护数据库:限流控制回源速率,熔断在 DB 明显异常时快速失败,降级返回兜底数据或静态数据。
这类兜底牺牲的是部分体验,保住的是系统整体。比如商品推荐暂时返回默认列表,排行榜暂时返回上一轮结果,都比把数据库打崩更可控。
五、和击穿、穿透的区别
缓存击穿是单个热点 key 过期,大量请求集中打到 DB,核心解法是互斥重建、逻辑过期。缓存穿透是查根本不存在的数据,核心解法是缓存空值、布隆过滤器、参数校验。缓存雪崩则是大量 key 或缓存层整体失效,核心解法是打散、预热、高可用、限流降级。
六、面试追问与工程边界
面试官常会问“TTL 随机值是不是越大越好”。不是。随机窗口太小,打散效果不明显;太大,会让数据新鲜度不可控。一般要结合业务容忍的数据延迟、缓存量级和回源能力估算窗口。
还要区分缓存雪崩和服务雪崩。缓存雪崩是缓存层失效导致 DB 被打爆;服务雪崩是一个服务故障沿调用链扩散。缓存雪崩可能引发服务雪崩,所以除了缓存侧治理,还要有调用侧超时、隔离、熔断和降级。
七、常见误区与追问
这道题不能只背概念,要把「缓存雪崩」放回真实分布式系统里解释:参与方是谁、状态怎么流转、失败后怎么恢复,以及它在一致性、性能、可用性之间做了什么取舍。
| 回答层次 | 要讲清的内容 | 容易漏掉的边界 |
|---|---|---|
| 核心结论 | 缓存雪崩是大量 key 同时失效或缓存集群故障,导致请求集中打到数据库 | 不要停在名词解释 |
| 流程机制 | 大量 key 同时过期或 Redis 故障 -> 缓存命中率骤降 -> 请求涌向数据库 -> 数据库变慢或宕机 -> 通过过期打散、限流降级和多级缓存止血 | 说明触发方、存储方、确认点和兜底 |
| 工程取舍 | 10 万个 key 都设置 00:00 过期,零点后数据库可能瞬间承接全部读流量 | 缓存提升吞吐但会引入旧值、热点、内存和失效风暴问题 |
缓存雪崩 面试拆解:
1. 大量 key 同时过期或 Redis 故障
2. 缓存命中率骤降
3. 请求涌向数据库
4. 数据库变慢或宕机
5. 通过过期打散、限流降级和多级缓存止血
记忆钩子:先说明缓存承担的读写压力,再拆穿透、击穿、雪崩、热点、一致性和淘汰策略;回答时要紧扣「缓存雪崩」这道题,不要把相邻概念混成一段泛泛的分布式套话。
- 误区:雪崩只是 Redis 宕机。 大量 key 同时过期也会造成雪崩。
- 误区:统一 TTL 方便管理就最好。 统一过期会制造同一时间失效尖峰,应加随机抖动。
- 误区:只靠数据库扩容兜底。 雪崩流量可能远超数据库容量,需要缓存高可用、限流和降级。
- 追问:TTL 如何打散? 基础 TTL 加随机值,例如 3600s + random(0,600s)。
- 追问:缓存集群故障怎么办? 本地缓存、限流、降级、熔断和 Redis 高可用切换。
- 追问:和击穿区别是什么? 雪崩是大量 key 或集群级问题,击穿是单个热点 key。
八、加强记忆
缓存雪崩的关键词是“大面积失效”:要么大量 key 同时过期,要么缓存集群整体不可用。治理要分层:TTL 加随机值和预热解决集中过期,Redis 高可用和多级缓存解决缓存故障,限流、熔断、降级保护数据库。击穿看单个热点,穿透看不存在数据,雪崩看大批量失效。