缓存预热是在项目启动后、用户访问前将数据提前存入Redis。逻辑过期方案因缓存不存在时直接返回空,必须预热才能生效。常用预热方法包括项目启动时自动加载、接口手动触发及测试时手动查询。
Redis缓存预热:概念与实现方法详解
时间:2026-06-07
浏览:488
文章目录
1. 什么叫「缓存预热」?
一句话概括:项目启动之后、用户正式访问之前,先把数据提前塞进 Redis。不让用户的第一次请求去承担建缓存的代价,而是由开发者自己动手,提前把缓存建好。

简而言之:预热 = 项目启动后、用户访问前,提前把数据存进 Redis。
换句话说,就是:不让用户第一次访问时才去建缓存,而是我们自己提前把缓存建好。这才叫预热。
2. 为什么逻辑过期必须预热?
这个问题很关键。之所以强调逻辑过期需要预热,核心原因在于它的代码逻辑是这么写的:
if (缓存不存在) { return null; // 不查库、不建缓存}
看到了吗?如果缓存不存在,它会直接返回空,根本不会主动去数据库查数据、重建缓存。也就是说,它没有“自动补位”的能力。所以,如果一开始不把缓存预热好,用户一上来就撞上空的 Redis,那他们什么也拿不到。缓存必须提前就存在,否则逻辑过期方案就彻底失效了。
3. 到底怎么预热?(3 种最简单方法)
直接上干货,这三种方法最常用、也最实用。
方法 1:项目启动时自动加载(最常用)
用 Spring 的 @PostConstruct 注解就能搞定:
@PostConstructpublic void preloadHotShops() { // 1. 查出所有热点店铺(比如前100个) List hotShops = list(); // 2. 逐个写入 Redis(逻辑过期方式) for (Shop shop : hotShops) { saveShop2Redis(shop.getId(), 30L); }}
效果就是:项目一启动,自动把热门店铺数据存进 Redis。用户访问时,Redis 里已经有了,缓存命中率直接拉满。
方法 2:写个接口手动触发(测试最方便)
@GetMapping("/preload/shop/{id}")public Result preload(@PathVariable Long id) { saveShop2Redis(id, 30L); return Result.ok("预热成功");}
调用一下 /preload/shop/1,缓存就建好了。这个方法在测试阶段特别顺手,想预热哪个就热哪个。
方法 3:测试时随便查一次就预热
更直接的做法,就是手动调用一次查询方法:
queryWithLogicalExpire(1L);
这个方法内部会走到 saveShop2Redis(id, 20L);,缓存也就建起来了。虽然有点“暴力”,但也算是一种手动预热,适合快速验证。
saveShop2Redis 是干嘛的?
一句话总结:它就是专门负责把数据库里的店铺数据查出来,装进逻辑过期格式,然后塞进 Redis 的工具方法。
private void saveShop2Redis(Long id, Long expireSeconds) { // 1. 根据id查数据库 Shop shop = getById(id); // 2. 封装成 RedisData(数据 + 过期时间) RedisData redisData = new RedisData(); redisData.setData(shop); redisData.setExpireTime(LocalDateTime.now().plusSeconds(expireSeconds)); // 3. 存进 Redis(不给key设过期时间!) stringRedisTemplate.opsForValue().set(CACHE_SHOP_KEY + id, JSONUtil.toJsonStr(redisData));}
它一共干 3 件事,环环相扣:
- 查数据库,拿到最新的店铺数据。
- 打包:把店铺数据和一个逻辑过期时间封装在一起。
- 存 Redis,注意,key 本身不设 Redis 级别的过期时间,因为它要靠逻辑过期来控制。
它在整个逻辑里的角色是什么?
- 缓存预热时 → 调用它,提前把数据放进 Redis。
- 缓存逻辑过期时 → 调用它,后台异步更新缓存。
说白了,它就是这个方案里,专门负责“往 Redis 里写入逻辑过期格式的缓存”的核心工具方法,地位相当关键。
实用工具推荐
绿化、压缩、噪点和虚拟水印,自由调节做旧程度。
选择画质和输出格式,预览压缩前后的大小。