20.redis之雪崩
缓存雪崩
1.核心定义
- 概念:指缓存层中大量的 Key 在同一时刻集体过期,或者 Redis 服务宕机,导致所有的请求流量瞬间穿过缓存层,像雪崩一样全部砸向数据库。
- 关键特征:
范围:是 “面” 的问题(区别于“击穿”的单点问题)。
后果:数据库连接池瞬间打满 -> 报错/超时 -> 上游服务线程堆积 -> 整个系统链路崩溃(级联故障)。
2.诱发场景与根因
-
逻辑性雪崩(TTL 同步)
场景:批量导入数据(如电商大促商品、日终批处理),设置了相同的过期时间(如统一 expire 1h)。
结果:到了过期那一秒,这批数据集体消失。解决办法
代码层:TTL 随机化 (Jitter)
适用场景:逻辑性雪崩(大量 Key 同时过期)。
原理:在原有的过期时间基础上,增加一个随机偏差值,将流量波峰“摊平”。
公式:Final_TTL = Base_Time + Random(0, Gap_Time)// ❌ 错误写法:大家都活 1 小时 // redis.setEx(key, 3600, val); // ✅ 正确写法:1小时 + (0~300秒随机) // 这样 100 万个 Key 的过期时间就会分散在 5 分钟内,数据库压力平缓 int baseTTL = 3600; int jitter = new Random().nextInt(300); redis.setEx(key, baseTTL + jitter, val);预案层:缓存预热 (Warm-up)
适用场景:系统上线、大促活动开始前。
策略:通过脚本提前将热点数据加载到 Redis,避免上线瞬间流量直接打库。
注意:预热时必须也要使用“TTL 随机化”策略,否则预热的数据会在之后同时过期。 -
物理性雪崩(服务不可用)
场景:Redis 实例宕机、机房断网、分片故障。
结果:物理意义上的“无缓存可用”。解决办法
架构层:高可用设计 (High Availability)
核心概念:在 Redis 的世界里,实现高可用的核心思路只有一条:冗余(Redundancy)。 简单说就是:不要把鸡蛋放在一个篮子里。如果一个 Redis 挂了,必须立马有替补队员顶上去。
这是一个有趣的知识点,分以下几种情况:-
主从模式 (Master-Slave) —— “师徒制”
这是最基础的模式。
架构:一个师父 (Master),带着几个徒弟 (Slave)。
规则:
Master:负责写(增删改)。Master 收到数据后,会偷偷同步给 Slave。
Slave:负责读(查)。
优点:读写分离,分担了压力。
致命缺点:不是真正的高可用!
如果Master 挂了,Slave 不敢篡位。整个系统就不能写了,必须等管理员半夜爬起来手动重启 Master。这显然不符合“高可用”的要求。 -
哨兵模式 (Sentinel) —— “保安队长”
为了解决主从模式中“Master 挂了没人管”的问题,Redis 引入了 Sentinel(哨兵)。
角色:在 Redis 旁边,专门再运行几个监控程序,叫哨兵。
工作流程:
监控:哨兵一直盯着 Master:“你还活着吗?”
发现故障:如果 Master 不回话了,哨兵们会开会投票:“Master 是不是挂了?”
自动选主:如果确认挂了,哨兵会从剩下的 Slave 中选出一个最优秀的,提拔它成为新的 Master。
通知:告诉所有的客户端(你的 Java 代码):“地址变了啊,以后去连这个新老大。” -
集群模式 (Cluster) —— “分布式合伙人”
如果你的数据量超级大(比如 100G),一台机器内存根本装不下怎么办?或者流量太大,一台 Master 哪怕有哨兵保着,CPU 也扛不住怎么办? 这时候就需要 Redis Cluster。
架构:好几个 Master 一起干活,每个人负责一部分数据(分片 Sharding)。
Master A:负责存 ID 0-3000 的数据。
Master B:负责存 ID 3001-6000 的数据。
...
高可用机制:每个 Master 后面都挂着自己的 Slave。
如果 Master A 挂了,Master A 的徒弟会自动顶上去。
整个集群依然能正常工作,只会丢失极少部分数据(故障切换期间)。
-

浙公网安备 33010602011771号