零件到体系
系列走到这里, Cache Aside、穿透、击穿、雪崩、一致性、双删、binlog、预热、热 Key、大 Key、淘汰、过期、复制、持久化、哨兵、Cluster、多级缓存、命中率——十八个零件全部到齐。本篇不做新知识,只做一件事:把零件装回一台机器,用一个请求的完整旅程,把每一篇讲过的机制放回它真实的位置。
一次读请求的旅程
用户请求商品详情,到达应用服务的一刻,漏斗开始逐层过滤:L1 本地缓存(第 16 篇)——纳秒级,热数据在这里就被接住,根本不产生网络流量;L2 Redis(第 15 篇 Cluster)——本地未命中,按槽位路由到正确分片,亚毫秒级命中后回填 L1;回源 DB——最后一级,也是要被保护的一级。回源之前,四道防线依次把关:布隆过滤器与空值缓存拦住不存在的 key(穿透篇);互斥重建或逻辑过期保证热点重建只有一次回源(击穿篇);TTL 打散与本地缓存兜底让集体失效无从发生(雪崩篇);限流降级守住 DB 的最后门口(限流系列的多级防线)。回源结果同时灌进 L2 与 L1,下一个请求从最上层就走完了。
读: 请求 ──> L1命中? 返回
│未命中
v
L2(Redis)命中? 回填L1并返回
│未命中
v
布隆过滤 ──> 互斥重建 ──> 回源DB ──> 灌L2+L1一次写请求的旅程
写路径的目标只有一个:库与缓存最终一致,且不一致窗口尽量短。主链路按一致性篇的定论走:更新 DB(事务内)、删除 L2 缓存、广播失效事件清掉各实例的 L1(多级缓存篇);加固链路是两道保险:延迟双删清掉竞态回填的旧值(第 7 篇),binlog 订阅做业务代码之外的第二道删除、失败进 MQ 重试到成功为止;最终兜底是TTL——无论前面哪一环失守,最坏情况被封顶在过期时间之内。
写: update db ──> del L2 ──> 广播清L1
└──> 延迟双删(异步) ──> binlog订阅(第二道) ──> MQ重试
└──> TTL 兜底:不一致窗口的最终上限治理与基建的站位
读写两条链路之外,还有两排「场外人员」。治理面:预热(第 8 篇)在上线与大促前把漏斗灌满;热 Key 探测与多副本(第 9 篇)看住流量的倾斜;大 Key 扫描与拆分(第 10 篇)看住数据的畸形;命中率监控(第 17 篇)是整个体系的体检表。基建面:淘汰策略(第 11 篇)管内存代谢;过期删除与主从复制(第 12 篇)管数据流转;持久化(第 13 篇)管重启不丢光;哨兵(第 14 篇)管自动切主——它们不出现在请求的路径上,却决定了路径上的每一环有多可靠。
一张图记住整个系列
如果只能带走三句话,是这三句:读靠漏斗——层级越靠上越好,每一级都有存在的量化理由;写靠兜底——删除加双删加 binlog 加 TTL,层层保险压住不一致窗口;体系靠指标——命中率、内存水位、主从延迟、大 Key 报表,看得见才治得了。缓存没有银弹,只有层层设防、各就各位的工程。
图有了,机制懂了,但纸上得来终觉浅——下一篇不讲机制,只讲故事:七个真实形态的缓存事故,看看这些机制是怎么在实战里被忽视、又怎么在事故报告里被写回来的。
评论 (0)