Redis 缓存穿透、击穿与雪崩:原理与应对实战
【摘要】 在高并发的后端服务里,Redis 几乎是标配的缓存层。它能把数据库的读压力降下来,但用不好也会带来新的故障:明明加了缓存,数据库还是被打垮了。今天就来聊聊缓存最常见的三个"坑"——穿透、击穿、雪崩,以及各自的应对办法。 一、缓存穿透:查不存在的东西,查一次打一次库现象:请求查询一个根本不存在的数据(比如 id = -1 的用户),缓存里没有,数据库里也没有,于是每次请求都会穿透缓存直达数据库...
在高并发的后端服务里,Redis 几乎是标配的缓存层。它能把数据库的读压力降下来,但用不好也会带来新的故障:明明加了缓存,数据库还是被打垮了。今天就来聊聊缓存最常见的三个"坑"——穿透、击穿、雪崩,以及各自的应对办法。
一、缓存穿透:查不存在的东西,查一次打一次库
现象:请求查询一个根本不存在的数据(比如 id = -1 的用户),缓存里没有,数据库里也没有,于是每次请求都会穿透缓存直达数据库。如果有人恶意构造大量这样的请求,数据库很快就会被拖垮。
应对方法:
- 缓存空值:查询结果为空时,也把"空"缓存起来(设置较短的过期时间,比如 5 分钟),下次同样的请求直接命中空缓存,不再打库。
- 布隆过滤器:在缓存前加一层布隆过滤器,把所有可能存在的 key 预先放进去。请求先过布隆过滤器,不存在的 key 直接返回,根本不会走到缓存和数据库。
// 缓存空值示例
String value = redis.get(key);
if (value == null) {
value = db.query(key);
if (value == null) {
redis.setex(key, 300, "NULL"); // 空值也缓存 5 分钟
return null;
}
redis.setex(key, 3600, value);
}
return value;
二、缓存击穿:热点 Key 过期瞬间,大量请求打到库
现象:某个热点 Key(比如秒杀商品的库存)恰好过期,而此时又有海量并发请求进来,缓存形同虚设,所有请求一股脑涌向数据库。
应对方法:
- 互斥锁:只允许一个线程去数据库加载数据并回写缓存,其他线程等待或返回旧值。实现简单,是最常用的方案。
- 热点数据永不过期:对极端热点的数据不设置过期时间,由后台任务定时异步更新;或者采用"逻辑过期"策略。
// 互斥锁示例(简化)
if (redis.setnx(lockKey, "1", 10)) { // 拿到锁的线程查库
try {
value = db.query(key);
redis.setex(key, 3600, value);
} finally {
redis.del(lockKey);
}
} else {
Thread.sleep(50); // 没拿到锁,稍等后重试
return redis.get(key);
}
三、缓存雪崩:大量 Key 同时过期,数据库被"雪崩"压垮
现象:大批缓存在同一时刻过期(比如上线时批量写入的缓存都设置了相同的 TTL),或者 Redis 集群整体宕机,请求洪流瞬间全部压到数据库上。
应对方法:
- 过期时间加随机值:给 TTL 加上一个随机偏移量,比如 TTL = 基础时间 + random(0, 300),避免 Key 集体过期。
- 多级缓存:本地缓存(如 Caffeine)+ Redis 两级,Redis 挂了还有本地缓存顶一阵。
- 限流与熔断:在网关或服务层做限流,极端情况下熔断降级,保证核心链路可用。
- Redis 高可用:主从 + 哨兵或 Cluster 模式,避免单点故障。
四、三者的区别,一句话总结
| 问题 | 本质 | 关键词 |
|---|---|---|
| 缓存穿透 | 查不存在的数据 | 空值缓存 / 布隆过滤器 |
| 缓存击穿 | 热点 Key 过期 | 互斥锁 / 热点永不过期 |
| 缓存雪崩 | 大量 Key 同时失效 | TTL 随机化 / 多级缓存 / 限流熔断 |
三者经常被混淆,记住:穿透是"查无此物",击穿是"热点过期",雪崩是"集体过期"。
结语
缓存是把双刃剑,穿透、击穿、雪崩是每个后端开发者迟早会遇到的三道坎。理解它们的成因,提前把空值缓存、互斥锁、TTL 随机化这些手段用上,就能让缓存真正成为系统的"护城河",而不是新的故障源。希望这篇短文能帮你避开这些坑。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)