缓存穿透、失效、雪崩如何解决¶
一、三个问题对比¶
| 穿透 | 失效 | 雪崩 | |
|---|---|---|---|
| 原因 | 查不存在的数据 | 大量缓存同时过期 | Redis 节点挂了 |
| 请求打到 DB | 每次 | 过期瞬间 | 大面积 |
| 数据 | 不存在 | 存在但缓存没了 | 存在但缓存不可用 |
二、缓存穿透¶
查一个 DB 和缓存都没有的数据,每次都打到 DB。
解决¶
1. 缓存空值¶
Object v = redis.get(key);
if (v == null) {
v = db.get(key);
redis.set(key, v == null ? "NULL" : v, 60); // 空值也缓存
}
缺点:空值多了浪费内存。
2. 布隆过滤器¶
请求先过布隆过滤器,不存在直接拦截。
详见 布隆过滤器。
3. 参数校验¶
恶意请求直接拦。
三、缓存失效¶
热点 Key 同时过期,瞬间打到 DB。
解决¶
1. 随机 TTL¶
2. 互斥锁重建¶
见 热点缓存重建。
3. 逻辑过期¶
不设 TTL,异步更新。
四、缓存雪崩¶
Redis 节点挂了,大量请求直接到 DB。
解决¶
1. Redis 高可用¶
主从 + 哨兵 / Cluster,一个节点挂了其他顶上。
2. 限流降级¶
DB 扛不住时限流,返回默认值。
3. 多级缓存¶
本地缓存兜底。
五、总结¶
| 问题 | 核心方案 |
|---|---|
| 穿透 | 布隆过滤器 + 缓存空值 |
| 失效 | 随机 TTL + 互斥锁 |
| 雪崩 | Redis 高可用 + 限流降级 |
面试加分
穿透是"查不存在",失效是"同时过期",雪崩是"缓存挂了"。三个问题要分清。