当前位置: 首页 > news >正文

双层缓存的预热策略

双层缓存(L1 本地缓存 + L2 分布式缓存)是高并发系统的经典架构。然而,冷启动缓存失效后重建瞬间的缓存缺失,会导致大量请求穿透到后端,引发性能尖峰甚至系统崩溃。预热策略就是为了解决这个问题。


一、预热的核心问题

1.1 冷启动的三个问题

问题描述影响
缓存全空系统刚启动,两级缓存都为空所有请求直击数据库
热点数据缺失本地缓存有限,热点数据可能被淘汰本地缓存命中率低
雪崩效应大量缓存同时失效或重建数据库瞬间过载

1.2 预热的目标


二、本地缓存(Caffeine)预热策略

2.1 启动时同步加载

最简单的预热方式:应用启动时,从数据库或 Redis 加载热点数据到本地缓存。

java

@Component public class LocalCacheWarmer { @Autowired private ProductMapper productMapper; @Autowired private RedisTemplate<String, Object> redisTemplate; private final Cache<String, Product> localCache = Caffeine.newBuilder() .maximumSize(10_000) .expireAfterWrite(5, TimeUnit.MINUTES) .build(); @EventListener(ApplicationReadyEvent.class) public void warmUp() { log.info("开始预热本地缓存..."); long start = System.currentTimeMillis(); // 策略1: 加载数据库中的热点商品(按销量排序) List<Product> hotProducts = productMapper.selectTopHotProducts(5000); for (Product product : hotProducts) { localCache.put("product:" + product.getId(), product); } // 策略2: 从 Redis 加载预定义的热点 Key 列表 Set<String> hotKeys = redisTemplate.opsForSet().members("config:hot_keys"); for (String key : hotKeys) { Product product = (Product) redisTemplate.opsForValue().get(key); if (product != null) { localCache.put(key, product); } } long cost = System.currentTimeMillis() - start; log.info("本地缓存预热完成,加载 {} 条数据,耗时 {} ms", localCache.estimatedSize(), cost); } }

2.2 使用 Caffeine 的 refreshAfterWrite 自动刷新

Caffeine 的 refreshAfterWrite 可以在缓存过期后异步刷新,避免缓存击穿。

java

@Configuration public class CaffeineConfig { @Bean public Cache<String, Product> productCache(ProductLoader productLoader) { return Caffeine.newBuilder() .maximumSize(10_000) // 写入后 30 秒刷新(异步) .refreshAfterWrite(30, TimeUnit.SECONDS) // 写入后 5 分钟过期 .expireAfterWrite(5, TimeUnit.MINUTES) .build(new CacheLoader<String, Product>() { @Override public @Nullable Product load(String key) throws Exception {
http://www.jsqmd.com/news/639427/

相关文章:

  • ejabberd多租户架构实现:如何为多个组织提供服务的终极指南
  • 20252110史菲宇Python实验二
  • 探寻靠谱的定制衣柜品牌,唐家定制衣柜厂家直销性价比如何 - myqiye
  • AI手势识别与追踪镜像体验:无需GPU,CPU秒级检测21个手部关键点
  • 前端精读周刊:终极Web Workers多线程编程实战指南
  • LeetCodehot100-78 子集
  • 用STM32状态机搞定多按键复用:从洗衣机控制面板到你的项目实战
  • ESP32连接HC-SR04超声波模块,这个5V电平转换的坑你踩过吗?
  • 从零开始:用Rainmeter打造个性化Windows桌面的完整指南
  • 深度探索开源工具:实战应用《怪物猎人世界》游戏数据叠加层
  • Android系统性能优化:工程师指南与面试准备
  • Win11Debloat终极指南:三分钟彻底优化Windows系统,性能飙升40%
  • 公司电脑被管控?离线搞定瑞萨RZ/N2L开发环境(e2_studio + FSP + GCC ARM)
  • Z-Image-Turbo_Sugar脸部Lora应用实践:为独立设计师提供AI面部风格参考图
  • KMS_VL_ALL_AIO:Windows和Office智能激活解决方案
  • 3分钟掌握Windows风扇智能控制:FanControl终极指南解决电脑噪音与散热难题
  • Qwen3-ASR-1.7B与数据库集成:语音识别结果存储与检索方案
  • 当孩子面临情绪问题时,如何有效提升注意力和管理冲动行为?
  • Qwen3.5-2B模型解决运维难题:403 Forbidden等常见错误排查
  • AI专著撰写全流程:工具深度解读,助你轻松产出优质专著
  • 2026工业级实战:C#上位机+YOLOv11+ByteTrack实现产线多目标跟踪与PLC联动控制
  • 端侧AI工程师技术开发指南
  • 雷达信号处理 python实现(二)相干与非相干积累 带宽与分辨率的关系
  • 【无人机】1.从零编译Betaflight/Cleanflight固件:针对STM32F103的实战指南
  • 5分钟掌握本地视频字幕提取:Video-subtitle-extractor终极指南
  • TurboDiffusion快速部署:基于Wan2.1/Wan2.2,开机即用免配置
  • 从零到一:RK3576开发板固件烧录全流程实战解析
  • Ostrakon-VL-8B数据库集成应用:构建可检索的多模态知识库
  • OneinStack备份与恢复:7种云存储方案完整教程
  • 【2026年最新600套毕设项目分享】畅阅读微信小程序(30050)