大促前缓存预热的本质,是把用户最可能点击的数据提前塞进离他最近的内存里,优先级排序是:热点商品>活动会场>用户画像>配置字典,而不是把全量数据盲目灌进Redis。
第一步:先分清哪些数据值得进缓存
不是所有数据都适合预热。 判断标准就一条:这数据在开售瞬间会不会被高并发读爆? 从历年大促经验来看,值得预热的数据分四层。
高热度商品数据(第一优先级)
- 秒杀商品、限量款、爆款SKU的详情页结构化信息、主图URL、规格参数、卖点文案
- 实时库存状态:注意不是把所有库存都缓存,而是把可售库存的阈值状态缓存(如”有货””紧张””售罄”)
- 价格快照:大促价、券后价、到手价的计算结果,避免开售瞬间大量请求穿透到价格服务
活动会场与楼层配置
- 首页Banner位、金刚区图标、楼层商品坑位的展示配置,这部分数据经常是运营在后台配好的JSON结构
- 会场页的排序规则和商品池ID列表,开售时用户刷新首页会同时拉取这批数据
- 优惠券领取页的券模板信息和剩余量,抢券场景比商品详情更容易产生热点
用户维度的会话与画像数据
- 登录用户的购物车商品清单(需做脱敏和压缩),大促开场用户第一个动作往往是看购物车
- 用户最近30天的浏览/收藏偏好标签,用于推荐排序,但只预热活跃度Top20%的用户,长尾用户按需回源
- 用户领券记录和可用券列表,这个数据不进缓存的话,下单时会穿透到券中心,极容易拖垮数据库
配置类与字典类数据
- 运费模板、售后策略、支付方式开关、配送区域表
- 类目属性字典、品牌库、区域码表
- 风控规则的黑白名单IP段、设备指纹库
第二步:怎么筛选出正确的预热清单
不要拍脑袋选商品,用数据和规则选出热点池。
基于历史流量做加权
取最近7天的UV、PV、加购数、收藏数,按权重打分:热度分 = 0.4×昨日UV + 0.3×加购率 + 0.2×转化率 + 0.1×收藏率,然后按分数降序取前1万-5万个SKU作为预热池(具体量级看你的服务器内存余量)。
基于运营策略补充人工池
运营主推的爆款、直播间的专属链接、新奇特商品,即使历史数据不高也必须加入。更关键的是把”预热池”和”报名大促的商品池”做交集,只保留两者重叠的部分。
排除掉绝不进缓存的数据
- 超过1MB的大字段(如富文本详情、视频URL列表)
- 维度极高且base无热点的数据(如每个用户的个性化弹窗配置)
- 强一致性的数据(如支付回调状态、订单状态流转)
第三步:大促前缓存预热的正确步骤与脚本思路
流程比工具重要,分四步走最稳。
容量评估与缓存水位规划(T-7天)
先摸清Redis集群的内存水位,预留30%的buffer给大促期间的增量写入,如果当前使用率已超70%,需要先做key清理或扩容。
构建预热任务清单(T-3天)
用离线任务从数据仓库或备库中捞数据,生成一个preheat_list文件,每行一个key和对应的缓存策略。核心是构造缓存key时要和线上运行时完全一致,避免预热了个寂寞。
执行预热脚本(T-1天或T-2小时)
常见方案有四种:
- 利用缓存框架的启动预热功能:像Caffeine的
CacheLoader或Spring Cache的@Cacheable配合ApplicationRunner初始化时加载 - 写一个独立的预热程序:用多线程并发从DB读取数据,管道写入Redis,注意控制批量大小(建议每次
pipeline100-200个key) - 直接压测流量触发:在T-1天晚上用线上回放流量打一波,让热点key自然进入缓存(此方案风险较高,容易把DB打挂,新手慎用)
- 历史缓存日志重放:把去年大促同期的Redis
monitor或slowlog抓出来,去掉过期key后重新灌入
预热效果验证与补热
预热完成后,不要直接开售,做一轮检查:
redis-cli --bigkeys看大key分布是否异常info stats看keyspace_hits和keyspace_misses的比值,若命中率已低于80%,说明预热数据不对路,要立即补热- 用压测工具模拟QPS打到预估峰值的50%,观察
latency和rejected指标
第四步:多级缓存架构下的分层预热策略
大促场景下没人敢只靠一层Redis,需要做多级配合。
本地缓存层(Caffeine/Guava)
适合放稳定性极高的字典数据、类目树、区域表,预热方式最简单:服务启动时从Redis加载到本地JVM,并设置合理的过期时间(建议4小时),大促期间这层的命中率直接决定Redis能扛多大压力。
分布式缓存层(Redis Cluster)
- 热点商品和库存放这一层,这部分数据要求极短的过期时间(建议5-10分钟动态续期),防止大促期间价格或库存变了还停留在缓存里
- 用逻辑过期代替物理过期:不给key设TTL,而是存一个过期时间戳在value里,后台异步续期,这样能避免大促瞬间的缓存雪崩
CDN/边缘节点层
静态资源(图片、CSS/JS、商品楼层模板)的预热走CDN刷新接口,重点刷新活动页涉及的所有资源URL,图片域名和大促页面路径要提前一天完成预热,不然全国CDN节点回源会把源站带宽打满。
大促热门问题排查指南
预热后Redis内存被撑爆了怎么办?
先确认是不是把长尾数据也塞进去了,解决思路是给预热任务加一个内存配额上限,比如最多占集群总内存的45%,如果已经爆了,优先淘汰非核心key,用unlink异步删除大key,别用del,最保险的方案是给预热池数据都加上较短的TTL(如1小时),让没被访问的key自动消失。
预热期间服务恰好重启了,缓存数据丢了要不要立刻补?
看阶段,如果大促还没正式开始,让预热任务重新跑一遍即可,不要用定时任务反复扫全量,如果已经开售,服务重启后先保证热点Top100的key立即重建(可以在ApplicationRunner里强制加载),其他key在流量驱动下按需回源,同时开启缓存穿透保护(布隆过滤器或空值缓存),防止瞬时高并发打到DB上。
预热的数据和线上下单的数据不一致怎么办?
行业共识是:缓存里的价格和库存永远是近似值,最终一致性由数据库保证,操作上把库存预热到“可超卖阈值”(比如实际库存的1.2倍),下单时通过扣减脚本(Lua)做最终校验,超卖的订单走人工退款或自动取消,价格不一致问题靠短TTL+延迟双删解决:写库成功后先删缓存,等500毫秒再删一次,确保读请求不会把旧值再捞回去。
大促预热的本质是用离线时间换取在线时间的确定性,把Redis当成一个有生命力的哨兵,它替你把最难扛的流量挡在数据库外面。预热只是前戏,真正考验系统的是开售前10分钟的动态流量调度和降级预案,把上述清单按优先级固化成自动化任务,你会发现大促当天的告警量会少得让你不习惯。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/773361.html


