Redis缓存预热:概念与实现方法详解

作者:技术拾光时间:2026-06-07 08:48:02浏览:489

缓存预热是在项目启动后、用户访问前将数据提前存入Redis。逻辑过期方案因缓存不存在时直接返回空,必须预热才能生效。常用预热方法包括项目启动时自动加载、接口手动触发及测试时手动查询。

1. 什么叫「缓存预热」?

一句话概括:项目启动之后、用户正式访问之前,先把数据提前塞进 Redis。不让用户的第一次请求去承担建缓存的代价,而是由开发者自己动手,提前把缓存建好。

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 件事,环环相扣:

  1. 查数据库,拿到最新的店铺数据。
  2. 打包:把店铺数据和一个逻辑过期时间封装在一起。
  3. 存 Redis,注意,key 本身不设 Redis 级别的过期时间,因为它要靠逻辑过期来控制。

它在整个逻辑里的角色是什么?

  • 缓存预热时 → 调用它,提前把数据放进 Redis。
  • 缓存逻辑过期时 → 调用它,后台异步更新缓存。

说白了,它就是这个方案里,专门负责“往 Redis 里写入逻辑过期格式的缓存”的核心工具方法,地位相当关键。