如何实现缓存的预热

缓存预热是在系统启动或者在业务高峰期之前,将一些数据加载到缓存中,以提高系统的性能和响应速度。

启动过程中预热

比较常见的一种实现方式就是在系统启动的时候预热,这种方式一般对于本地缓存十分常见,因为本地缓存本身就是基于JVM内存的,当应用重启时,本地缓存就会被清空,而在应用启动之后,就需要把本地缓存的内容预热好。这样才能起到缓存的效果。

那么,一种有效的方式就是基于Spring来实现。在Spring应用程序启动时,可以通过监听应用启动事件,或者在应用的初始化阶段,将需要缓存的数据加载到缓存中。这可以通过在启动时调用相关服务或者数据访问层的方法来实现。

Spring其实提供了一系列事件及扩展点,可以让我们在他的生命周期的各个阶段做我们想做的事情。如基于ApplicationReadyEvent、CommandLineRunner、InitializingBean、@PostConstruct等。

定时任务

在启动过程中预热有一个问题,那就是一旦启动之后,如果需要预热新的数据,或者需要修改数据,就不支持了,那么,在应用的运行过程中,我们也是可以通过定时任务来实现缓存的更新预热的。

我们通常依赖这种方式来确保缓存中的数据是最新的,避免因为业务数据的变化而导致缓存数据过时。

在Spring中,想要实现一个定时任务也挺简单的,基于@Scheduled就可以轻易实现

java 复制代码
@Scheduled(cron = "0 0 1 * * ?") // 每天凌晨1点执行
public void scheduledCachePreload() {
    // 执行缓存预热逻辑
    // ...
}

动态加载

java 复制代码
public Data fetchData(String key) {
    // 先检查缓存中是否存在数据
    Data cachedData = cache.get(key);

    if (cachedData == null) {
        // 如果缓存中不存在,根据业务需求加载数据到缓存中
        // ...
    }

    return cachedData;
}

就像Redis可以基于用户的查询来进行延迟删除key一样 ,我们也可以基于用户的查询进行延迟的更新缓存。

也就是说,在用户请求到来时,根据用户的访问模式和业务需求,动态地将数据加载到缓存中。这种方式更加灵活,可以根据实际需求选择性地预热缓存。

缓存加载器

一些缓存框架提供了缓存加载器的机制,可以在缓存中不存在数据时,自动调用加载器加载数据到缓存中。这样可以简化缓存预热的逻辑。如Caffeine中就有这样的功能:

java 复制代码
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class MyCacheService {

    private final LoadingCache<String, String> cache;

    public MyCacheService() {
        this.cache = Caffeine.newBuilder()
                .refreshAfterWrite(1, TimeUnit.MINUTES)  // 配置自动刷新,1分钟刷新一次
                .build(key -> loadDataFromSource(key));  // 使用加载器加载数据
    }

    public String getValue(String key) {
        return cache.get(key);
    }

    private String loadDataFromSource(String key) {
        // 从数据源加载数据的逻辑
        // 这里只是一个示例,实际应用中可能是从数据库、外部服务等获取数据
        System.out.println("Loading data for key: " + key);
        return "Value for " + key;
    }
}

在上面的例子中,我们使用 Caffeine.newBuilder().refreshAfterWrite(1, TimeUnit.MINUTES) 配置了缓存的自动刷新机制,即每个缓存项在写入后的1分钟内,如果有读请求,Caffeine 会自动触发数据的刷新。

loadDataFromSource 方法是用于加载数据的自定义方法。你可以在这个方法中实现从数据源(例如数据库、外部服务)加载数据的逻辑。

相关推荐
卿雪4 小时前
Redis 线程模型:Redis为什么这么快?Redis为什么引入多线程?
java·数据库·redis·sql·mysql·缓存·golang
爬山算法4 小时前
Redis(167)如何使用Redis实现分布式缓存?
redis·分布式·缓存
源代码•宸7 小时前
分布式缓存-GO(项目整体架构简介、Ubuntu 22.04 64位安装GoLang、安装Docker、解决Go module 的依赖问题)
经验分享·分布式·后端·ubuntu·缓存·docker·golang
K3v8 小时前
【nvm安装14.x失败】nvm设置国内镜像源 npm设置全局缓存以及全局包目录
前端·缓存·npm
博语小屋9 小时前
生产者消费者模型
linux·分布式·缓存
所得皆惊喜9 小时前
REDIS04_管道的概念、案列演示、管道总结
redis·缓存
羑悻的小杀马特10 小时前
Stream消息队列+地理空间计算+HyperLogLog去重,SCAN安全遍历+RESP协议全解析,一文把它啃透!
数据库·redis·安全·缓存·空间计算·resp
JIAWAP10 小时前
Redis数据安全性分析之RDB详解
数据库·redis·分布式·缓存
2501_9167665411 小时前
【Mybatis】延迟加载与多级缓存
缓存·mybatis
雨落秋垣11 小时前
SpringCache 缓存:注意事项、问题解决与优化策略
java·spring·缓存