不能全量重载,因为会压垮数据库和Redis并引发二次雪崩;应按业务优先级分批加载,只预热不可降级、无fallback、高并发必查的key,并确保结构一致、TTL随机、主从同步完成后再放量。
雪崩发生时,Redis里大量 key 同时失效或服务刚恢复,如果一上来就执行全量数据加载(比如从 MySQL 读全部商品、用户、订单表再塞进 Redis),会立刻引发两个问题:一是数据库瞬间被压垮,二是 Redis 自身写入吞吐打满,主从同步延迟飙升,甚至触发 OOM 或 maxmemory 驱逐。这不是“预热”,是“二次雪崩”。
真正决定加载顺序的不是数据量大小,而是「哪些请求最先打进来、且失败后影响最大」。例如电商大促场景:
sku_info 和 cart:uid: 这类 key 必须第一批加载——用户加购、下单路径直接中断user_profile 可第二批——登录成功后才查,有兜底逻辑(如返回默认头像)activity_rule 若已过期,可第三批或跳过——活动结束就不需要了核心原则:只预热「当前业务链路中不可降级、无 fallback、高并发必查」的 key。
别用单个脚本硬编码所有表。推荐用配置驱动 + 异步队列方式:
cache-warmup-priority.yaml),每条含 keyPattern、dataSource、batchSize、priority
priority 升序拉取数据,但每批加载完必须检查 redis.info("stats").get("used_memory_human") 和 redis.info("replication").get("master_last_io_seconds_ago"),超阈值则暂停pipeline 批量写入,禁用 SET 单条;低优 key 可走异步线程池 + 限速(如每秒 ≤500 条)SCAN 全量扫 DB 表——改用业务方提供的 hot_sku_ids、recent_login_uids 等轻量集合分批预热不是“分批塞数据”就完事。以下三点常被跳过,却直接导致预热无效:
value 结构必须一致——比如预热用的是 JSON 字符串,而线上代码期望的是 HASH 结构,加载后照样 nil
setWithRandomExpiry() 方法,基础 TTL 加 ±10% 随机偏移INFO replication 中 master_sync_in_progress:0 和 slave_repl_offset 与 master_repl_offset 差值 最麻烦的永远不是“怎么加载”,而是“怎么确认这批数据真能被业务代码正确消费”。上线前务必用真实流量回放验证第一批次 key 的命中率和响应耗时。