Redis 缓存预热怎么做?冷启动会带来什么问题?
简化版
缓存预热是在流量到来前,把高频数据提前加载到 Redis,避免系统冷启动时大量请求直接打数据库。常见做法有发布后预热、定时任务预热、热点数据预热、灰度预热和访问触发的渐进预热。
详细版
冷启动时 Redis 里没有热点数据,第一波请求会集中回源数据库。如果是首页、商品详情、配置、榜单这类高并发读场景,数据库可能被瞬时打满。
预热要先定义“预热哪些数据”,再定义“什么时候预热、用多大并发、失败怎么补”。不能把全库数据都塞进 Redis,否则会造成内存浪费、网络压力和淘汰抖动。
好的方案通常是:从访问日志或业务规则识别热点,分批写入 Redis,设置随机 TTL,验证命中率和加载耗时,并保留限流、降级和兜底回源。
完整版教学
一、冷启动为什么危险
缓存的价值来自命中率。系统刚发布、Redis 重启、缓存被清空或新活动上线时,热点 key 还没进入缓存,这时每个请求都可能变成数据库查询。
假设商品详情 QPS 是 5000,缓存命中率平时 95%,数据库实际承受 250 QPS。冷启动命中率变成 0%,数据库会瞬间承受 5000 QPS,压力放大 20 倍。
这就是预热要解决的问题:不要等真实用户请求来“撞库填缓存”。
二、预热数据从哪里来
预热不是全量灌数据,而是找高价值数据。来源通常有三类:业务确定的热点、历史访问日志统计出的热点、运营活动即将曝光的数据。
例如电商首页要预热活动商品、排行榜、类目配置;内容站要预热热门文章;SaaS 系统要预热租户配置和权限字典。
可以用一个简单公式给候选 key 排序:
预热优先级 = 访问频次 * 重建成本 * 业务重要性
访问少、重建便宜、过期快的数据,不值得提前占 Redis 内存。
三、预热流程怎么设计
一个稳的预热流程通常是“取候选 → 查源数据 → 组装 value → 批量写 Redis → 校验命中”。中间每一步都要可限速、可重试、可观察。
热点清单 -> 分片任务 -> 查数据库/服务 -> SETEX + 随机 TTL -> 抽样 GET 校验
批量写入可以用 pipeline,但不要无限并发。比如每批 500 个 key、每秒 20 批,实际写入约 1 万 key/s,要结合 Redis CPU、网络和数据库读取能力调整。
四、预热和发布流程怎么结合
发布后直接切全量流量是最容易翻车的。更好的做法是先预热新版本依赖的缓存,再灰度放量,观察命中率、Redis 延迟和数据库 QPS。
如果 key 格式变了,例如从 goods:1001 变成 goods:v2:1001,旧缓存不能命中新代码。发布前就要预热 v2 key,避免“代码一上线全量冷缓存”。
| 时机 | 适合场景 | 注意点 |
|---|---|---|
| 发布前预热 | key 规则变更、新页面上线 | 防止新版本冷启动 |
| 定时预热 | 榜单、配置、活动页 | 避免集中写入 |
| 访问触发 | 长尾数据 | 要限流和互斥重建 |
五、预热失败如何兜底
预热一定会失败:源库慢、网络抖动、Redis 写入超时、数据序列化异常都可能发生。不能让预热失败变成上线失败,也不能沉默失败。
工程上要记录失败 key,重试有限次数,最后进入告警或降级列表。真实请求回源时仍要有互斥重建、限流、默认值或降级页面。
预热只是降低冷启动概率,不是替代运行时保护。没有运行时保护的预热方案,遇到缓存清空或节点切换仍然会暴露。
六、常见误区与追问
- 误区:预热就是把所有数据塞进 Redis。 全量灌入会浪费内存,还可能挤掉真正热点。
- 误区:有预热就不需要缓存击穿保护。 预热失败、过期、重启都会让请求回源,运行时兜底仍必须存在。
- 误区:pipeline 越大越快。 批次过大可能撑爆输出缓冲、拉高延迟或给网络造成尖峰。
- 追问:如何判断预热有效? 看预热耗时、失败 key 数、上线后命中率、数据库 QPS 和 Redis p99 延迟。
- 追问:key 版本升级怎么预热? 提前写新版本 key,灰度流量验证命中,确认稳定后再清理旧版本 key。
七、加强记忆
记忆钩子:缓存预热不是“多写点缓存”,而是给流量开闸前先把最可能被访问、最贵的那批数据摆到 Redis 前台。
回答这题时要把“预热对象、预热时机、写入节奏、失败兜底、指标验证”串起来。面试官想听的不是一个定时任务,而是一套能扛发布和活动流量的缓存启动方案。