大促前缓存预热该预热哪些数据?一句话:只预热高频读、低修改、强时效的热点数据,商品详情、库存、活动配置、用户券包四类优先,全量预热既浪费内存又拖慢启动。
大促流量峰值往往是日常的几倍甚至十几倍,数据库连接池和磁盘IO在秒杀瞬间最容易被打满,缓存预热这件事,本质是提前把会被反复读取的数据放进Redis或本地缓存,避免流量直接打到MySQL,预热错了数据,等于给数据库埋雷。
大促前缓存预热该预热哪些数据?先给数据分三类
不是所有数据都值得预热,判断标准只有一条:读多写少、时效可控、访问集中,根据这个标准,预热数据可以分成三个优先级。
第一优先级:商品详情与基础信息
主图、卖点、规格参数、详情页HTML片段,这类数据变化频率很低,一次写入缓存可以扛住整个大促周期,预热方式很简单:用脚本从商品表批量读取最近7天有加购或收藏记录的SKU,写入Redis的String或Hash结构。
- 从MySQL导出热点商品ID列表,保存为
hot_sku_ids.txt - 执行
cat hot_sku_ids.txt | redis-cli --pipe,配合SET product:detail:{sku_id} {json}批量写入 - 设置过期时间为大促结束时间加30分钟,避免活动结束后缓存还占用内存
第二优先级:库存与价格
库存数量和到手价是用户下单前最后一步必读数据,库存变更非常频繁,预热不是把库存值写死,而是把库存扣减逻辑依赖的初始库存和价格快照提前加载。
- 预热时写入
stock:init:{sku_id}作为基准库存 - 实际扣减走Redis原子操作
DECR或Lua脚本 - 价格数据写入
price:promo:{sku_id},过期时间按活动场次设置,比如前2小时秒杀价结束就自动失效
第三优先级:活动配置与页面装修
大促会场、优惠券发放规则、满减计算参数、楼层排序数据,这类数据读取频率高,但更新集中在活动开始前,预热时把整个活动配置序列化成JSON,写入cache:activity:{act_id},并设置比活动周期略长一点的过期时间。
行业共识认为,活动配置类数据如果不预热,大促开场瞬间大量请求同时解析同一个JSON,CPU和内存带宽都会出现尖刺,提前写入缓存能把这部分压力从应用层转移到Redis。
电商大促缓存预热方案怎么做:从时间窗口到执行命令
知道预热哪些数据还不够,执行方案必须卡准时间点。电商大促缓存预热方案怎么做,关键在预热的启动时间和回滚策略。
预热时间窗口怎么定
- 活动开始前2小时至30分钟是黄金窗口,太早预热,数据可能被自然过期淘汰;太晚预热,预热任务本身会和流量抢资源。
- 对于大型平台,可以按分会场分批次预热,避免单次预热任务打满Redis带宽。
- 预热前先检查Redis内存使用率,可用
INFO memory查看used_memory_human,确保剩余容量能容纳新增热点数据。
预热执行路径与命令示例
以Java应用为例,预热任务通常放在独立Job里,通过配置中心触发。
- 从配置中心读取活动ID和预热灰度比例
- 查询数据库或数仓导出的热点商品清单
- 分页读取商品数据,每页200条,多线程写入Redis
- 写入后执行
EXPIRE设置合理过期时间 - 预热完成后输出日志,记录写入成功条数和耗时
如果使用Canal监听MySQL binlog,可以在预热阶段临时开启全量同步任务,把商品表数据实时同步到缓存,这种方案的优点是数据一致性较高,缺点是部署复杂度也高。
双11大促缓存预热热点数据有哪些常见坑
双11这类大促流量峰值具有明显脉冲特征,预热热点数据时最容易踩三个坑。
缓存预热和缓存穿透:区别与联系
缓存预热和缓存穿透区别在于:预热是主动把可能存在的数据提前加载到缓存,穿透是查询一个缓存和数据库都不存在的数据导致每次请求都打到数据库,预热做得好能减少一部分穿透风险,但无法完全解决穿透,因为穿透针对的是不存在的数据。
- 对不存在的商品ID返回空值并缓存短时间,比如
SET product:detail:{sku_id} "NULL" EX 60 - 使用布隆过滤器拦截无效ID
- 预热脚本里只处理存在的ID,过滤掉已被删除的商品
预热数据过期与雪崩
大促期间热点商品缓存如果集中过期,会导致大量请求同时回源数据库,也就是缓存雪崩,预热时必须给过期时间加随机偏移量,避免同一批数据同一秒失效。
- 设置
EXPIRE key ttl + random(0, 300),单位为秒 - 对于核心商品,使用逻辑过期而不物理删除,后台异步刷新
- 预热时给不同分类的商品设置不同基准TTL,比如服饰类7200秒,数码类3600秒
预热数据与实际数据不一致
库存、价格、优惠券状态可能在预热后发生变化,如果预热脚本没有监听变更事件,用户可能看到旧价格或已抢光的库存。
- 预热完成后开启binlog订阅,捕获商品、库存、价格表的UPDATE事件
- 对发生变更的SKU,执行单条
DEL再重新写入最新值 - 活动开始前30分钟内暂停所有非紧急变更,进入数据冻结期
低成本缓存预热方案:中小团队不用堆机器
很多中小团队一提到预热就想到扩容Redis集群、上多级缓存,其实低成本缓存预热方案的核心不是加机器,而是提高预热命中率。
用本地缓存兜底热点Top100
如果Redis容量有限,可以把大促期间访问量最高的前100个商品直接写进应用本地缓存Caffeine或Guava Cache,本地缓存读取延迟低,不占用Redis内存。
- 从日志系统统计最近7天商品访问量,取前100个SKU
- 应用启动时从数据库加载这100个商品的详情和价格
- 设置本地缓存过期时间为10分钟,后台每5分钟异步刷新
- Redis作为二级缓存,命中未击中再查本地,最后查数据库
利用定时任务模拟真实流量预热
不引入额外中间件,直接用Linux crontab或Spring Task定时预热。
/30 /usr/local/bin/preheat.sh >> /var/log/preheat.log 2>&1
preheat.sh脚本里用curl请求预热接口,接口内部完成热点数据查询和写入,这样能保证缓存里始终有最近30分钟的热点数据。
杭州电商公司缓存预热实操:三步完成预热
以杭州某电商公司大促准备为例,他们团队只有两名后端工程师,照样完成了一套可用的预热流程,地域上杭州电商氛围浓厚,类似体量的公司很多,这套步骤可以直接复用。
第一步:从日志里捞热点
使用awk和sort命令统计Nginx访问日志,提取商品ID出现次数,排序后取前500个。
cat access.log | awk '{print $7}' | grep -oP 'sku_id=K[0-9]+' | sort | uniq -c | sort -rn | head -500 > hot_skus.txt
第二步:写预热Job
在项目里新增一个PreheatJob类,实现ApplicationRunner接口,应用启动后延迟60秒执行,方法内读取hot_skus.txt,多线程查询数据库并SET到Redis,每个Key设置随机过期时间,范围在5400秒到7200秒之间。
第三步:监控预热效果
预热前后分别执行redis-cli --stat查看命中率,大促开始后如果命中率低于预期,立即执行手动预热脚本补偿热点商品,监控指标主要看keyspace_hits和keyspace_misses的比值。
业内专家指出,中小团队预热失败往往不是技术问题,而是没有提前验证预热脚本在线上数据量下的执行时间,最好在预发环境用线上数据量跑一遍,确认不会拖垮数据库。
大促前缓存预热该预热哪些数据:常见问答
缓存预热需要预热多少数据量?
没有固定标准,取决于公司体量和活动规模,多数情况下,预热数据量控制在Redis总内存的较低比例比较稳妥,中小电商活动预热几万到几十万个Key,大型平台可能到百万级,原则是只预热能被访问到的热点,不追求全量覆盖。
缓存预热和缓存穿透区别是什么?
缓存预热是提前加载可能被访问的合法数据,缓存穿透是请求根本不存在的数据,预热解决的是已有数据快速读取问题,穿透解决的是非法数据防护问题,两者场景不同,方案也不同,不能混为一谈。
预热时Redis内存满了怎么办?
优先使用maxmemory-policy allkeys-lru淘汰策略,如果内存仍不足,执行redis-cli --bigkeys找出大Key,压缩或拆分,最后的选择才是临时扩容,但扩容需要提前规划,大促当天加机器往往来不及同步数据。
大促前缓存预热该预热哪些数据,核心是抓住高频读、低变更、强时效这条主线,把有限资源押在商品详情、库存、活动配置和用户券包上,配合合理过期时间和回滚方案,中小团队也能平稳扛住峰值。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/635969.html





