如何实现缓存的预热

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

启动过程中预热

比较常见的一种实现方式就是在系统启动的时候预热,这种方式一般对于本地缓存十分常见,因为本地缓存本身就是基于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 方法是用于加载数据的自定义方法。你可以在这个方法中实现从数据源(例如数据库、外部服务)加载数据的逻辑。

相关推荐
大猫子的技术日记5 小时前
[百题重刷]前缀和 + Hash 表:缓存思想, 消除重复计算
java·缓存·哈希算法
愤怒的山羊6 小时前
jetcache List 缓存, json 序列化 泛型解析成了 JsonObject 处理
缓存·json·list
树在风中摇曳7 小时前
带哨兵位的双向循环链表详解(含 C 代码)+ LeetCode138 深度解析 + 顺序表 vs 链表缓存机制对比(图解 CPU 层级)
c语言·链表·缓存
斯文~10 小时前
「玩透ESA」站点配置阿里云ESA全站加速+自定义规则缓存
阿里云·缓存·云计算·cdn·esa
S***t71410 小时前
Python装饰器实现缓存
缓存
天硕国产存储技术站11 小时前
3000次零失误验证,天硕工业级SSD筑牢国产SSD安全存储方案
缓存·固态硬盘·国产ssd
前端炒粉14 小时前
35.LRU 缓存
开发语言·javascript·数据结构·算法·缓存·js
努力发光的程序员21 小时前
互联网大厂Java面试:从Spring Boot到微服务架构
spring boot·缓存·微服务·消息队列·rabbitmq·spring security·安全框架
zero13_小葵司1 天前
JavaScript性能优化系列(八)弱网环境体验优化 - 8.3 数据预加载与缓存:提前缓存关键数据
javascript·缓存·性能优化
CS_浮鱼1 天前
【Linux进阶】mmap实战:文件映射、进程通信与LRU缓存
linux·运维·c++·缓存