从小白到架构师 | 缓存预热

缓存预热指的是在系统启动或上线前,提前将经常访问的数据加载到缓存中,以避免在系统刚启动时,用户大量请求直接访问数据库,导致数据库压力过大或系统性能下降。通过缓存预热,可以确保系统一上线就能提供快速的响应时间和良好的用户体验。

缓存预热的几种解决方案:

  • 手动预热:系统管理员在系统启动前,手动触发一些接口,将数据加载到缓存中。
  • 自动预热
  • 定时预热

缓存预热的几种解决方案

自动预热

系统启动时,自动加载预定义的一些数据到缓存中。

java 复制代码
public class CacheService {
    private final Map<String, Data> cache = new ConcurrentHashMap<>();
    private final Database database = new Database();

    public CacheService() {
        // 系统启动时自动预热
        autoPreheat();
    }

    private void autoPreheat() {
        // 自动预热常用数据
        cache.put("key1", database.getData("key1"));
        cache.put("key2", database.getData("key2"));
    }

    public Data getData(String key) {
        return cache.get(key);
    }
}
定时预热

系统定期自动加载常用数据到缓存中,确保缓存中的数据是最新的。

java 复制代码
public class CacheService {
    private final Map<String, Data> cache = new ConcurrentHashMap<>();
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private final Database database = new Database();
    private final long CACHE_REFRESH_INTERVAL = 30; // 每 30 秒预热一次

    public CacheService() {
        // 启动定时预热任务
        scheduler.scheduleAtFixedRate(this::preheatCache, 0, CACHE_REFRESH_INTERVAL, TimeUnit.SECONDS);
    }

    private void preheatCache() {
        // 定时预热常用数据
        cache.put("key1", database.getData("key1"));
        cache.put("key2", database.getData("key2"));
    }

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

    public void shutdown() {
        scheduler.shutdown();
    }
}

如何确定需要预先缓存哪些数据

确定需要预热哪些数据是缓存预热的关键和难点之一。选择错误的数据预热不仅浪费资源,也无法提高系统性能。以下是一些确定需要预热数据的方法。

基于历史访问数据

分析系统的历史访问日志,找出访问频率较高的数据,优先将这些数据缓存。

java 复制代码
public class CacheService {
    private final Map<String, Data> cache = new ConcurrentHashMap<>();
    private final Database database = new Database();
    private final AccessLog accessLog = new AccessLog();

    public CacheService() {
        // 启动时预热缓存
        preheatCache();
    }

    private void preheatCache() {
        for (String key : accessLog.getFrequentKeys()) {
            cache.put(key, database.getData(key));
        }
    }

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

class Data {
    // 模拟数据类
}

class Database {
    public Data getData(String key) {
        // 从数据库获取数据
        return new Data();
    }
}

class AccessLog {
    // 模拟访问日志
    public List<String> getFrequentKeys() {
        // 返回访问频率较高的key
        return Arrays.asList("key1", "key2", "key3");
    }
}
基于业务逻辑

根据业务场景,确定哪些数据在系统启动时是必需的。例如,电子商务网站的首页商品推荐,新闻网站的头条新闻等。

java 复制代码
public class CacheService {
    private final Map<String, Data> cache = new ConcurrentHashMap<>();
    private final Database database = new Database();

    public CacheService() {
        // 启动时预热缓存
        preheatCache();
    }

    private void preheatCache() {
        // 根据业务逻辑预热数据
        cache.put("homepageData", database.getData("homepageData"));
        cache.put("popularProducts", database.getData("popularProducts"));
    }

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

class Data {
    // 模拟数据类
}

class Database {
    public Data getData(String key) {
        // 从数据库获取数据
        return new Data();
    }
}
相关推荐
while(1){yan}5 小时前
Spring事务
java·数据库·spring boot·后端·java-ee·mybatis
盛世宏博北京5 小时前
高效环境管控:楼宇机房以太网温湿度精准监测系统方案
开发语言·数据库·php·以太网温湿度变送器
运维行者_5 小时前
2026 技术升级,OpManager 新增 AI 网络拓扑与带宽预测功能
运维·网络·数据库·人工智能·安全·web安全·自动化
gfdhy5 小时前
【C++实战】多态版商品库存管理系统:从设计到实现,吃透面向对象核心
开发语言·数据库·c++·microsoft·毕业设计·毕设
Elastic 中国社区官方博客5 小时前
Elasticsearch:上下文工程 vs. 提示词工程
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
小唐同学爱学习5 小时前
如何解决海量数据存储
java·数据库·spring boot·mysql
*.✧屠苏隐遥(ノ◕ヮ◕)ノ*.✧6 小时前
《苍穹外卖》- day01 开发环境搭建
spring boot·后端·spring·maven·intellij-idea·mybatis
wWYy.6 小时前
详解redis(15):缓存雪崩
数据库·redis·缓存
zzcufo6 小时前
多邻国第五阶段第13部分
java·开发语言·数据库
这周也會开心6 小时前
Redis相关知识点
数据库·redis·缓存