缓存预热

重启或发布后缓存为空,流量直压数据库;通过预热脚本回填热点数据、延迟放量与分批导流降低冲击,预热进度要与放量节奏联动。

缓存预热解决什么

重启、发布或扩容后缓存是空的,此时如果直接放开全量流量,所有请求都会回源查询数据库——命中率从接近 100% 跌到接近 0,数据库在短时间内承受平时数倍的压力,极端情况下直接被打垮。缓存预热的思路是:在放量之前把热点数据回填到缓存,并让放量节奏与预热进度联动,命中率恢复到阈值后再逐步放开全部流量。

基本信息

对象热点商品、配置、权限等重启后高频访问的数据
手段发布前离线加载到缓存;灰度放量控制回源
联动缓存命中率恢复到阈值后再逐步放开全量
兜底未预热完成的键要有互斥重建与限流保护,防止并发回源

典型使用场景

  • 服务重启与版本发布:避免发布瞬间的缓存空窗
  • 大促与活动前:按活动热度清单预先加载相关数据
  • 缓存集群扩容或迁移:新节点加入后需要回填热点
  • 数据库故障恢复后:集中回源会造成二次冲击,需提前预热
  • 批量数据更新后:更新完成后主动回填,避免持续穿透

预热流程

预热流程
1. 生成清单:按历史访问榜与活动计划产出待预热键列表
2. 分批回填:脚本按批次加载并控制速率,避免压垮数据源
3. 校验:抽查关键键的缓存值与数据源一致
4. 联动放量:命中率与回源量达标后逐级放开流量
5. 兜底:未完成的键配互斥重建与限流,防止并发回源
# 预热脚本要支持中断续跑,并按批次记录进度

预热维度

维度做法注意
触发时机发布重启后、大促活动前、批量更新后、缓存扩容后错过时机的预热没有意义
粒度控制按业务域分批,核心链路键优先一次性全量加载会给数据源造成压力
版本对齐预热数据与发布版本核对加载旧版本数据会造成长时间错误
进度可观测输出已加载键数、命中率与回源量无进度指标时放量只能凭感觉

使用要点

  • 清单要随业务演进维护:活动热点与日常热点不同,按活动单独准备
  • 回填速率要有上限:脚本把数据库打满的案例并不少见
  • 增量补偿:发布期间的新数据同步写缓存,弥补预热期间的时间差
  • 回滚后清理已写入的键,防止旧版本数据残留在缓存里
  • 预热脚本支持中断续跑,按批次记录进度,长任务中断后不必从头开始
预热清单要随业务演进维护:活动热点与日常热点不同,按活动单独准备,否则预热了日常热点却漏掉了真正会爆的键。
预热未完成就全量放行,等于让数据库一次性承受全部回源;放量节奏必须与命中率联动,而不是按固定时间表推进。

易错点

  • 重启后直接全量放行,缓存击穿打垮数据库,服务恢复时间被大幅拉长
  • 预热数据过期策略未同步,热点提前失效,预热效果在几分钟内消失
  • 回填脚本并发过高,把数据源打满,预热过程本身成为故障源
  • 预热数据与发布版本不一致,加载了旧版本数据,出现长时间数据错误
  • 预热脚本无进度与断点能力,中断后只能从头执行,长任务难以完成

数据来源与参考

  • AWS 白皮书:Database Caching Strategies Using Redis
  • 《高性能 MySQL(第 4 版)》
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌