一、缓存是把双刃剑
Redis 用得好,系统起飞;用不好,半夜救火。本文把缓存最常见的三大问题——穿透、击穿、雪崩——讲透,并给出可直接落地的代码方案。
二、缓存穿透:查不存在的数据
现象:请求一个数据库和缓存都没有的 key,每次都打到 DB。
方案 1:缓存空值
String val = redis.get(key);
if (val == null) {
val = db.query(key);
if (val == null) {
redis.setex(key, 300, ""); // 空值缓存 5 分钟
}
}
方案 2:布隆过滤器:在缓存前加一层 BloomFilter,不存在的 key 直接拦截。
三、缓存击穿:热点 key 过期瞬间
现象:某个爆款 key 突然失效,海量请求同时打到 DB。
方案:互斥锁(分布式锁)
String val = redis.get(key);
if (val == null) {
if (redis.setnx("lock:"+key, "1", 10)) { // 拿到锁
val = db.query(key);
redis.setex(key, 3600, val);
redis.del("lock:"+key);
} else {
Thread.sleep(50); // 没拿到锁,稍等重试
return getFromCache(key);
}
}
四、缓存雪崩:大量 key 同时失效
现象:批量 key 在同一时刻过期,DB 被瞬间压垮。
方案:过期时间加随机抖动
int base = 3600;
int jitter = new Random().nextInt(600); // 0~10分钟随机
redis.setex(key, base + jitter, val);
另外:核心数据可设逻辑过期(不真过期,后台异步刷新)。
五、防坑补充
- 缓存与数据库一致性:写时先更新 DB 再删缓存(Cache Aside),注意重试。
- 大 key 拆分:一个 hash 存万级字段会阻塞,拆成多个。
- 避免热 key 集中:Redis Cluster 分片 + 本地缓存二级兜底。
结语
三大坑记牢”空值、加锁、抖动”六字诀,再配合监控,Redis 就能稳稳扛住高并发。




