缓存穿透击穿雪崩终极对比
1.1 一张表封神——画这个就够了
graph LR subgraph "缓存穿透" P1["查什么:数据库中不存在的数据"] P2["根因:恶意攻击 / 不存在的 ID"] P3["现象:每个不存在 ID 都打到 DB<br/>缓存完全没挡住"] P4["范围:不限量的不同 key"] P5["比喻:一直有人问'有大象吗?'"] P6["解法:①缓存空值 ②布隆过滤器"] P7["速记:查不存在的 → 两道门拦住"] end subgraph "缓存击穿" B1["查什么:数据库中存在的数据"] B2["根因:热点 key 刚好过期"] B3["现象:同一个热点 ID 的请求<br/>瞬间全部打到 DB"] B4["范围:单个 key"] B5["比喻:全班同时问老师同一个问题"] B6["解法:①互斥锁 ②逻辑过期"] B7["速记:热点刚好过期 → 只让一个人去拿"] end subgraph "缓存雪崩" C1["查什么:数据库中存在的数据"] C2["根因:大量 key 同时过期或 Redis 挂了"] C3["现象:所有请求绕过缓存<br/>全部打到 DB"] C4["范围:大量 key / 整个 Redis"] C5["比喻:学校同时下课食堂窗口被冲"] C6["解法:①随机过期 ②多级缓存<br/>③限流降级 ④Redis 高可用"] C7["速记:大片一起过期 → 别挤在一起"] end
1.2 连环追问 —— 怎么从”背答案”变成”你在思考”
延伸提问:说说缓存穿透怎么解决?
你:布隆过滤器 + 缓存空值。
延伸提问:布隆过滤器有什么缺点?
你:① 不能删除元素——商品下架后布隆过滤器里还在,只能重建
② 有误判率——说"可能存在"时可能是误判
③ 需要提前知道数据量——初始化时就要预估数组大小
延伸提问:误判会导致什么?
你:误判说"可能存在"→ 放行去查 Redis → Redis 也没有 → 查 MySQL → MySQL 也没有
→ 这次被穿透了。但这只是"漏网之鱼"——概率很低(1% 以内),
比其他 99% 的流量被挡住,完全可接受。
加一层缓存空值兜底——偶尔漏过去的也被短时间缓存住。
延伸提问:为什么布隆过滤器不能删除?
你:因为它多个元素共享 bit。一个格子被 A、B、C 三个元素涂过,
你不能因为删了 A 就把这个格子清零——那样 B 和 C 也被"误删"了。
所以只能整个过滤器重建。
延伸提问:缓存击穿用互斥锁有什么风险?
你:① 锁超时——查 MySQL 太慢导致锁自动释放 → 多个请求同时查 MySQL → 互斥失效
② 锁竞争——几千个请求同时抢锁,对 Redis 也是额外压力
③ 死锁——锁没设超时 + 拿到锁的请求崩了 = 锁永远不释放
延伸提问:那逻辑过期有什么风险?
你:① 数据一致性——返回给用户的可能是几秒前的旧数据
② 预热依赖——系统启动时必须把热点数据加载进 Redis,否则第一次还是穿透
③ 内存占用——热点 key 物理上永不过期,可能撑大 Redis 内存(需要监控)
延伸提问:缓存雪崩的随机过期时间真的能解决吗?
你:只能说"缓解"——把同时过期变成分散过期。但如果 Redis 本身挂了,
随机过期也没用(Redis 都没了,谈什么过期)。所以雪崩需要多层防线——
随机过期 + 本地缓存 + 限流降级 + 高可用集群,一层一层补。
延伸提问:那你觉得本地缓存会有什么问题?
你:① 数据不一致——多台服务器各自的本地缓存更新不同步,
一台服务器缓存了新数据,另一台还是旧的
② 内存占用——每个进程各自维护一份缓存,总内存 = 单份 × 服务器数量
③ 冷启动——服务器重启后本地缓存是空的,需要从 Redis/MySQL 重新加载
所以本地缓存只适合存"变更极少的热点数据"——配置项、首页 Banner 之类。
速记卡(面试闪卡)
Q1:一句话讲清「缓存穿透击穿雪崩终极对比」到底是什么?
A:缓存三兄弟:穿透查不存在数据、击穿热点 key 刚好过期、雪崩大量 key 同时失效,根因解法各不相同。
Q2:1.1 缓存穿透 —— 怎么理解?
A:穿透=查数据库里根本不存在的数据,每个不存在的 ID 都打到 DB、缓存完全没挡住,根因是恶意攻击/不存在的 ID,范围不限量的不同 key。类比一直有人问”有大象吗”。解法两道门:① 缓存空值 ② 布隆过滤器。
Q3:1.1 缓存击穿 —— 怎么理解?
A:击穿=查数据库里存在的数据,但热点 key 刚好过期,同一热点 ID 的请求瞬间全打到 DB,范围是单个 key。类比全班同时问老师同一个问题。解法:① 互斥锁(只放一个人去查)② 逻辑过期(物理不过期,异步刷新)。
Q4:1.1 缓存雪崩 —— 怎么理解?
A:雪崩=大量 key 同时过期或 Redis 直接挂了,所有请求绕过缓存全打到 DB,范围是大量 key/整个 Redis。类比学校同时下课食堂窗口被冲。解法多层:① 随机过期 ② 多级缓存 ③ 限流降级 ④ Redis 高可用。
Q5:1.2 连环追问(布隆/锁/雪崩防御) —— 怎么理解?
A:布隆过滤器缺点:不能删(多元素共享 bit,清零会误删别人)、有误判率、需预估大小;误判只是低概率漏网,加缓存空值兜底。互斥锁风险:锁超时/锁竞争/死锁;逻辑过期风险:旧数据/预热依赖/内存撑大。雪崩随机过期只能”缓解”,Redis 挂了没用,需多层防线。
Q6:核心速记主线有哪些?
-
穿透:查不存在的→缓存空值+布隆过滤器
-
击穿:热点 key 过期→互斥锁+逻辑过期
-
雪崩:大量 key 同失效/Redis 挂→随机过期+多级缓存+限流+高可用
-
布隆缺点:不可删、有误判、需预估大小
-
互斥锁风险:超时/竞争/死锁;雪崩需多层防线
口诀
A:三兄弟名不同,穿透击穿雪崩
查无布隆拦门口,热点锁独扛
大片同失效,随机过期分散忙
多级缓存加限流,高可用才稳当