如何实现缓存的预热

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

启动过程中预热

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

相关推荐
engchina5 小时前
Python缓存利器:cachetools库详解
python·缓存·cachetools
Anpedestrian5 小时前
Mybatis中支持缓存的query与不支持缓存的query
java·缓存·mybatis
重庆大傑5 小时前
Redis 缓存问题及解决
数据库·redis·缓存
Peterpan0000015 小时前
玄机——第二章日志分析-redis应急响应 wp
数据库·redis·网络安全·缓存·安全威胁分析
xintaiideas20 小时前
设计⼀个⾼性能可⽀撑分桶多分⽚的库存中⼼,提供单库存分⽚不⾜扣减的合并库存功能,并提供商 品操作库存⼊库的渐进性⼊缓存的实现
缓存
DDD58520 小时前
Redis优化之持久化
数据库·redis·缓存
DKPT1 天前
如何确定MySQL中哪些列适合做索引
数据库·spring boot·spring·spring cloud·缓存
菜鸟小码1 天前
Redis基础教程(十一):Redis 发布订阅
redis·缓存·消息
青春丨猪头丨少年1 天前
Redis的两种持久化方案
数据库·redis·缓存
frans4x1 天前
操作系统缓存与缓冲
缓存