大家好,我是 31 岁的小米。如果你和我一样,经历过几次 Java 社招面试,你一定对一个问题不陌生:
你们系统的 Redis 缓存是怎么预热的?
这个问题看起来不复杂,但它偏偏是那种不会让你直接挂,却能精准拉开水平差距的问题。
因为它考的不是你会不会 Redis,而是你有没有真正参与过上线、扛过流量、踩过坑。
今天,我不打算用“概念 + 术语”的方式来讲。我想先给你讲一个生活里的故事。
故事开始:一家新开张的火锅店
假设你是老板,刚在商场里开了一家火锅店。开业当天,你做了一个“很程序员”的决定:
- 汤底不提前熬
- 菜不提前切
- 调料不提前配
理由也很充分:“客人点什么,我就现做,最新鲜。”
结果呢?
- 第一桌客人坐下
- 服务员跑来问你
- 你才开始烧水、切菜、调汤
- 10 分钟过去了,客人开始刷手机
- 20 分钟过去了,客人开始皱眉
- 30 分钟过去了,客人开始喊人
你一边忙,一边心里骂:“这届顾客,怎么这么没耐心?”
后来你发现,问题根本不在顾客,而在你自己。
火锅店的本质,不是“现做”,而是“高效出餐”。
你第二天换了策略:
- 早上提前熬好几锅汤
- 常点的菜提前切好
- 调料按固定比例配好
晚上高峰期一到:客人一来,直接下锅。
系统世界里的“火锅店”——Redis 冷启动
现在我们把视角切回到系统。如果把系统比作火锅店:
Redis 缓存预热,本质上就是:别等用户来了,才第一次查数据库。
什么是 Redis 缓存预热
在正式展开方案之前,我们先把概念说清楚。
Redis 缓存预热:是指在系统上线或服务启动之后,主动将高频访问、核心业务相关的数据提前加载到 Redis 缓存中,从而避免在真实用户请求到来时,因缓存未命中而大量访问数据库,造成性能抖动甚至雪崩。
一句更“人话”的总结:
缓存不是用来“等用户触发”的,而是用来“提前准备”的。
为什么一定要做缓存预热?
在面试中,如果你只说“提高性能”,那是远远不够的。
1、避免系统冷启动压力
系统刚上线时:
- Redis 是空的
- 所有请求都会直打数据库
- QPS 瞬间放大
数据库会经历一个非常痛苦的阶段。
2、防止缓存击穿和连锁反应
热点 key 在缓存里不存在时:
- 多线程并发查询数据库
- 数据库负载暴涨
- 甚至引发服务雪崩
3、提升首批用户体验
真实世界里:用户永远是第一印象决定生死。
方案一:手动触发缓存预热(最稳妥)
1、场景适用
- 上线频率低
- 数据结构复杂
- 希望可控性极高
2、思路
- 写一个缓存刷新接口
- 上线后由运维或开发手动触发
3、示例代码(Spring Boot + Redis)
4、优点 & 缺点
方案二:项目启动时自动加载(最常见)
1、场景适用
- 数据量不大
- 热点数据相对固定
- 系统启动可控
2、思路
利用 Spring 生命周期,在应用启动完成后执行缓存预热逻辑。
3、示例代码
4、优点 & 风险
方案三:定时刷新缓存(生产最常用)
1、场景适用
- 数据会变
- 热点随时间变化
- 长期运行系统
2、思路
- 定时从数据库加载热点数据
- 更新 Redis
- 保证缓存“始终是热的”
3、示例代码(Spring 定时任务)
三种方案怎么选?(面试必答)
面试加分回答模板:
“我们一般是启动时做一次缓存预热,同时通过定时任务周期性刷新热点数据,上线前如果有特殊活动,会人工触发一次。”
最后总结:缓存预热,是“提前准备的能力”
很多系统的问题,从来不是代码写得不好,而是你总在等事情发生之后,才开始补救。
缓存预热,其实是一种态度:我知道流量会来,所以我提前准备。
如果你能把这套逻辑讲清楚,面试官基本都会在心里给你打一个标签: “这个人,是真的上过线的。”
END
好朋友们,我们下篇见~
我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!