连载中 19/20

事故集锦:七次缓存事故复盘

2026-06-04 · 3753 阅读 · 0 评论 · 0 赞

知道,和做到之间

这一系列讲的所有机制,出事的时候团队几乎都「知道」——方案评审时提过、code review 时标过、事故复盘时写回过。知道与做到之间隔着的,就是这七个故事。案例形态取自真实事故的常见样貌,数据做了脱敏处理。

事故一:统一 TTL 的集体失效

现象:凌晨两点 DB 告警炸群,详情接口 RT 从 20ms 飙到 2s。根因:三天前的批量预热脚本给五十万热点数据统一设了「24 小时」TTL,同一秒集体过期,五万 QPS 全量回源——雪崩篇的标准剧本,一字不差。修复:TTL 加随机抖动重新预热;教训:预热脚本上线要过评审,「统一 TTL」这种写法直接打回。

事故二:先删缓存留下的旧值

现象:商品改价后,部分用户页面显示旧价,持续了一整晚。根因:写接口的顺序是先删缓存再更新库——删完到库更新完成之间,回源请求把旧值读出来又填了回去,旧值驻留到次日 TTL 到期(一致性篇的危险时序,真实发生)。修复:改为先更新库再删缓存,补上延迟双删;教训:读写交错不是理论概率,DB 慢一秒它就发生一次。

事故三:扩容解决不了的热 Key

现象:大促期间某分片 CPU 100%,运营要求「再加一台 Redis」。根因:一个爆款商品的 key 扛了三十万 QPS,key 哈希到固定槽住在固定分片——加机器它也不会搬家(热 Key 篇开头的第一句话)。修复:该 key 改多副本打散 + 应用侧本地缓存;教训:扩容前先看 key 级别的热度分布,别对单 key 风暴开错药。

事故四:DEL 卡住整个实例

现象:Redis 命令延迟周期性尖刺,每次两秒左右,找不到慢查询。根因:定时清理任务在删一个八百万成员的 set,DEL 逐个释放内存阻塞单线程——慢查询日志里看不到它,因为被卡的全体请求都在排队(大 Key 篇的连锁反应第一条)。修复:DEL 全部换 UNLINK,大 set 用 SCAN 分批清理;教训:单线程模型的 Redis,任何大动作都要问一句「这会占主线程多久」。

事故五:断线引发的全量同步风暴

现象:机房网络抖动两分钟,恢复后主库 CPU 打满、全站缓存接口变慢。根因:repl_backlog 用默认 1MB,写流量大的主库两分钟就把环形缓冲区覆盖了,从库 offset 失效,全部退化成全量同步——bgsave 加 RDB 传输的风暴(过期与复制篇的警告成真)。修复:repl-backlog-size 调到 256MB;教训:backlog 大小要用「写 QPS × 最长可容忍断线时间」算,不是默认值。

事故六:上线才炸的跨槽 MGET

现象:迁到 Cluster 后上线十分钟,批量接口大面积报错。根因:单机时代随手用的 MGET,在 Cluster 上 key 分散在不同槽,直接报 CROSSSLOT——开发环境三个 key 恰好同槽,测试全绿(Cluster 篇的代价清单第一条)。修复:客户端按槽分组再 pipeline;教训:跨槽限制要写进团队规范,测试环境的数据分布骗得过所有人。

事故七:脑裂蒸发的那几秒

现象:网络分区恢复后,用户投诉订单状态「回退」了。根因:分区期间哨兵完成切主,旧主还在孤立地接受写入;恢复后旧主降级从库并全量同步新主,分区期间写进旧主的数据全部蒸发(哨兵篇的脑裂暗坑)。修复:配置 min-replicas-to-write 1,孤立主库拒绝写入;教训:状态类数据放缓存要有「可能被蒸发」的心理预期,关键状态落库。

七个事故,七个教训,全部能在前面十六篇里找到机制原型——事故不是新知识,是没被执行的旧知识。最后一篇收官:把整个系列收进一张进阶地图。

503

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

#缓存事故#复盘#雪崩#热Key#大Key#脑裂

评论 (0)

相关推荐

连载中 12/20

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

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

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 5 阅读 · 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 赞