跳转至

缓存穿透、失效、雪崩如何解决

一、三个问题对比

穿透 失效 雪崩
原因 查不存在的数据 大量缓存同时过期 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

int ttl = 3600 + new Random().nextInt(300);  // 1小时 ±5分钟

2. 互斥锁重建

热点缓存重建

3. 逻辑过期

不设 TTL,异步更新。

四、缓存雪崩

Redis 节点挂了,大量请求直接到 DB。

解决

1. Redis 高可用

主从 + 哨兵 / Cluster,一个节点挂了其他顶上。

2. 限流降级

DB 扛不住时限流,返回默认值。

3. 多级缓存

本地缓存兜底。

五、总结

问题 核心方案
穿透 布隆过滤器 + 缓存空值
失效 随机 TTL + 互斥锁
雪崩 Redis 高可用 + 限流降级

面试加分

穿透是"查不存在",失效是"同时过期",雪崩是"缓存挂了"。三个问题要分清。