连载中 5/20

雪崩:同一夜失效的所有缓存

2026-05-26 · 6963 阅读 · 0 评论 · 0 赞

两种雪崩

缓存雪崩有两种形态。第一种:大批 key 同时到期——凌晨批量预热的热点数据统一设了 24 小时 TTL,第二天凌晨同一秒集体失效,或者在某一秒集中过了逻辑过期,读流量整体砸向 DB。第二种:Redis 实例整体宕机——缓存层直接消失,所有读请求回源,DB 瞬间接住平时十倍的流量。

它和限流系列第 1 篇的服务雪崩是近亲:那次讲的是慢下游拖死线程的级联传染,这次是缓存层集体失效后的流量错位——两者经常连环爆发,缓存雪崩触发服务雪崩。防线也从同一个思想出发:别让风险同时发生,别让流量无处可去

预防针:TTL 打散

对付「同时到期」,办法朴素而有效:给 TTL 加随机抖动,让到期时间摊开在一个区间里,任何时刻只有一小部分 key 过期:

int base   = 1800;                                       // 基础 30 分钟
int jitter = ThreadLocalRandom.current().nextInt(0, 600); // 0~10 分钟随机
redis.setex(key, base + jitter, toJson(detail));          // 30~40 分钟内摊开

批量预热的代码同样要打散——循环里给每个 key 独立的随机 TTL,否则预热脚本本身就成了雪崩的调度器。抖动幅度取 TTL 的一到三成,太小没效果,太大缓存水位抖动剧烈。

缓冲垫与止血带

Redis 整体挂掉时,TTL 打散无济于事——根本没缓存可打。此时的防线换一套:本地缓存挡在最前面,进程内的 Caffeine 里还留着的极热数据继续服务,分掉一部分流量;限流降级守住 DB 的门口——限流系列第 8 篇的多级防线在此复用:只放核心读流量到 DB,非核心接口直接降级返回缓存快照或兜底页;快速恢复靠 Redis 高可用——哨兵自动切换、集群副本顶上,让缓存层尽快回来,这部分到主从与哨兵篇展开。

层层设防,各就各位

把防线按时间排个序:预防——TTL 打散与预热,让雪崩没有发生条件;缓冲——本地缓存与客户端超时,让第一波冲击变软;止血——限流与降级,保住 DB 和核心链路;根治——主从哨兵与集群,让缓存层自身不再单点。四层各管一段,缺哪层哪层出事。

穿透、击穿、雪崩三只拦路虎到这里都过了招,但它们都还是「能用性」的问题。缓存真正的深水区在数据正确:库里的数据变了,缓存什么时候变、以什么顺序变——下一篇开始翻一致性这座大山。

503

10 年全栈工程师 · 503咖啡馆主理人

#缓存雪崩#TTL打散#本地缓存#限流降级#高可用

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞