第4章 · 缓存穿透、击穿、雪崩与解决方案
本章聚焦缓存经典三问——穿透、击穿、雪崩,这是大厂分布式缓存面的必考题。你需要清晰区分三种异常场景,并能给出布隆过滤器、互斥锁、缓存预热等实战方案。面试官不仅问“是什么”,更会深挖“如何设计”、”如何处理边界情况“。
知识结构速览
| 问题 | 表现 | 核心方案 | 关键注意事项 |
|---|---|---|---|
| 缓存穿透 | 请求的数据在缓存和DB中都不存在,大量请求穿过缓存直奔DB | 布隆过滤器;缓存空对象(短TTL) | 布隆只能判断“一定不存在”,无法精确删除;空对象可能导致内存占用 |
| 缓存击穿 | 某个热点key突然过期,超高并发同时请求DB | 互斥锁(分布式锁);提前续期(逻辑过期) | 锁超时时间要合理;避免使用本地锁,用Redis分布式锁 |
| 缓存雪崩 | 大量key同时过期或缓存节点宕机,DB被压垮 | 缓存预热+随机TTL;多级缓存;限流降级;集群高可用 | 预热时注意数据一致性;降级策略要预留 |
① 面试问题:什么是缓存穿透?你们如何解决?
面试官考察点:是否理解穿透底层原因,能否给出可落地的方案(布隆过滤器 vs 空对象),是否考虑过布隆的误判和删除问题。
回答框架:定义 → 危害 → 方案A(布隆过滤器)→ 方案B(缓存空对象)→ 如何选择
简短示例回答:缓存穿透指请求不存在的数据,DB也查不到,导致每次直接穿到DB。我们采用布隆过滤器预存所有商品ID,若布隆判断不存在则直接返回,拦截99%的非法请求。同时配合缓存空对象设短过期时间,兜底少数误判请求。
可能追问:布隆过滤器如何扩容?你能手写一个简单的布隆实现吗?如果布隆误判了怎么办?
避坑提醒:不要只说“用布隆过滤器”但答不上容量规划;布隆过滤器的位数组大小和哈希函数数量需要根据数据量预先计算,否则误判率飙升。
② 面试问题:缓存击穿和穿透有什么区别?如何防止击穿?
面试官考察点:能否区分两种场景,锁方案的设计细节,热点key识别机制,以及避免死锁或锁竞争。
回答框架:对比说明区别 → 击穿原因 → 解决方案(互斥锁/分布式锁)→ 锁流程 → 其他优化
简短示例回答:击穿是热点key过期,大量并发同时去DB加载。我们使用Redis SETNX实现分布式互斥锁,只有获取锁的线程能查DB并写缓存,其他线程等待或直接返回旧值。同时结合热点key自动识别,为热点key设置更长TTL。
可能追问:分布式锁超时时间怎么设?如果获取锁后处理很慢导致锁过期怎么办?如何避免锁的惊群效应?
避坑提醒:不要使用本地锁(synchronized)解决分布式击穿问题;锁粒度要细化到key级别,避免锁整个缓存。
③ 面试问题:什么是缓存雪崩?你在项目中是如何预防的?
面试官考察点:是否理解雪崩的两种成因(过期+宕机),能否给出体系化的预防措施,对高可用和限流降级的理解。
回答框架:定义 → 分类讨论(过期/宕机)→ 预防措施(预热+随机TTL、多级缓存、限流、集群)→ 兜底策略
简短示例回答:雪崩指大量key同时过期或缓存节点宕机导致DB压力激增。我们做缓存预热时给TTL加随机值(基础时间±30%),避免集中失效;同时搭建Redis哨兵集群保证高可用,并配置接口限流和降级开关,即使缓存全崩也能返回默认值。
可能追问:如果缓存节点宕机了,限流降级的阈值怎么定?多级缓存如何保证一致性?有没有遇到过雪崩复现的情况?
避坑提醒:不要只看“随机TTL”就以为解决了—还要考虑缓存节点宕机场景;降级策略需要提前测试,且要设计熔断恢复机制。
💡 面试加分点:在回答中主动提及布隆过滤器的误判率计算公式、分布式锁的RedLock算法、以及热key自动探测的统计窗口设计,能迅速拉开与普通候选人的差距。