缓存穿透、击穿、雪崩:三道经典题怎么答、怎么做?
知识背景
用 Redis 做 DB 前置缓存 时,高并发下会出现三类典型故障:穿透(查不存在的数据压垮 DB)、击穿(热点 key 过期瞬间大量打 DB)、雪崩(大量 key 同时过期或 Redis 宕机,DB 被拖死)。
面试与架构评审常考「定义 + 成因 + 方案」,实现上要结合 业务可接受的一致性。
知识详解与通俗解释
1. 缓存穿透
现象:查询一定不存在的数据(如恶意 id),缓存没有、DB 也没有,每次穿透到 DB。
思路:
- 布隆过滤器(或 Bitmap)先判「可能存在」再查 DB。
- 缓存空值(短 TTL),避免同一假 id 反复打 DB。
- 接口层 校验、限流。
通俗说:门卫先查黑名单,不存在的 id 连仓库门都不让进。
2. 缓存击穿
现象:单个热点 key 过期,瞬时并发都打 DB。
思路:
- 互斥锁(只让一个线程回源,其它等待或短暂降级)。
- 逻辑过期(永不过期物理 key,值里带逻辑时间,异步刷新)。
- 热点 key 永不过期 + 定时刷新(需评估内存与一致性)。
通俗说:爆款商品价签掉了,不能一千人同时冲进库房问价,要排队或先看昨天价签。
3. 缓存雪崩
现象:很多 key 同一时刻过期,或 Redis 集群整体故障,流量洪峰打满 DB。
思路:
- TTL 加随机抖动,避免齐刷刷过期。
- 高可用:主从、哨兵、集群;熔断降级。
- 多级缓存(本地 Caffeine + Redis)、队列削峰。
通俗说:别让所有优惠券零点整同时失效;Redis 挂了要有 Plan B。
4. 与「双写一致性」
上述三类偏 读缓存;写路径还有 先删缓存再写 DB / 先写 DB 再删缓存 等讨论,需单独设计,不要混为一谈。
总结
- 穿透:不存在的数据;过滤器 + 空值缓存 + 校验。
- 击穿:热点过期;锁 / 逻辑过期 / 异步刷新。
- 雪崩:集体过期或集群故障;随机 TTL + 高可用 + 降级。
- 方案都有成本,按热点与体量分级治理比一把梭更现实。