1. Caffeine 简介

Caffeine 是一个基于 Java 8 的高性能本地缓存库,由 Ben Manes 开发,旨在替代 Google Guava Cache,提供更优的缓存策略、更高的吞吐量和更灵活的配置。

核心优势

卓越的性能:采用优化的数据结构(如 Window TinyLFU 淘汰算法),减少锁竞争,提升并发访问效率。
灵活的缓存策略:支持基于大小、时间、权重等多种淘汰机制。
丰富的功能:自动刷新、异步加载、批量操作等高级特性。
无缝集成 Spring:与 Spring Cache 完美结合,轻松替换 Redis 或 Ehcache。


2. Caffeine 核心机制

2.1 缓存淘汰策略

Caffeine 提供多种缓存淘汰策略,防止内存无限增长:

策略方法说明
基于大小maximumSize(long)限制缓存最大条目数
基于权重maximumWeight(long) + weigher()根据条目权重限制缓存
基于时间expireAfterWrite / expireAfterAccess写入/访问后过期
手动淘汰invalidate(key) / invalidateAll()主动移除缓存

2.2 缓存加载方式

Caffeine 支持 同步加载异步加载

// 同步加载(阻塞)
LoadingCache<Key, Value> cache = Caffeine.newBuilder().build(key -> fetchFromDB(key));// 异步加载(非阻塞)
AsyncLoadingCache<Key, Value> asyncCache = Caffeine.newBuilder().buildAsync((key, executor) -> CompletableFuture.supplyAsync(() -> fetchFromDB(key), executor));

2.3 自动刷新机制

refreshAfterWrite 允许缓存条目在写入后一段时间自动刷新(异步,不阻塞请求):

LoadingCache<String, Data> cache = Caffeine.newBuilder().refreshAfterWrite(1, TimeUnit.MINUTES) // 1分钟后访问时触发刷新.build(this::loadDataFromDB);

注意:刷新时返回旧值,后台异步加载新值,适合高并发场景。


3. 代码实战:Caffeine + Spring Boot

3.1 基础配置

@Configuration
@EnableCaching
public class CacheConfig {@Beanpublic Caffeine<Object, Object> caffeineConfig() {return Caffeine.newBuilder().maximumSize(1000)          // 最大1000条.expireAfterWrite(10, TimeUnit.MINUTES) // 10分钟过期.refreshAfterWrite(1, TimeUnit.MINUTES); // 1分钟后自动刷新}@Beanpublic CacheManager cacheManager(Caffeine<Object, Object> caffeine) {CaffeineCacheManager cacheManager = new CaffeineCacheManager();cacheManager.setCaffeine(caffeine);return cacheManager;}
}

3.2 业务层使用

@Service
public class UserService {@Cacheable(value = "users", key = "#id") // 缓存名称为 "users"public User getUserById(Long id) {return userRepository.findById(id).orElse(null);}@CacheEvict(value = "users", key = "#id") // 删除缓存public void deleteUser(Long id) {userRepository.deleteById(id);}
}

4. 高级用法

4.1 多级缓存(Caffeine + Redis)

@Bean
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,Caffeine<Object, Object> caffeine
) {// 本地缓存CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();caffeineCacheManager.setCaffeine(caffeine);// Redis 缓存RedisCacheManager redisCacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(RedisCacheConfiguration.defaultCacheConfig()).build();// 组合缓存(先查本地,再查Redis)return new CompositeCacheManager(caffeineCacheManager, redisCacheManager);
}

4.2 批量操作优化

public Map<Long, User> batchGetUsers(List<Long> userIds) {// 批量查询缓存Map<Long, User> cachedUsers = cache.getAll(userIds);// 查找未命中的IDList<Long> missingIds = userIds.stream().filter(id -> !cachedUsers.containsKey(id)).collect(Collectors.toList());if (!missingIds.isEmpty()) {// 从DB加载并更新缓存Map<Long, User> dbUsers = userRepository.batchFindByIds(missingIds);cache.putAll(dbUsers);cachedUsers.putAll(dbUsers);}return cachedUsers;
}

5. 注意事项 & 最佳实践

5.1 缓存穿透问题

问题:恶意请求不存在的 key,导致频繁查询数据库。
解决方案

.build(key -> {User user = fetchFromDB(key);if (user == null) {return new NullValue(); // 缓存空对象}return user;
});

5.2 缓存雪崩

问题:大量缓存同时失效,导致数据库压力激增。
解决方案

.expireAfterWrite(10 + ThreadLocalRandom.current().nextInt(5), TimeUnit.MINUTES) // 随机过期时间

5.3 内存监控

Caffeine 提供统计信息:

.recordStats() // 启用统计
CacheStats stats = cache.stats();
System.out.println("命中率: " + stats.hitRate());
System.out.println("加载次数: " + stats.loadCount());

5.4 最佳实践

合理设置缓存大小:避免 OOM(如 maximumSize(10000))。
结合 TTL + 自动刷新:保证数据新鲜,同时避免阻塞请求。
分布式环境使用多级缓存:本地缓存 + Redis,减少网络开销。
监控缓存命中率:优化缓存策略,避免缓存失效风暴。


6. 总结

Caffeine 是 Java 生态中最强大的本地缓存库之一,适用于:

  • 高频访问的只读数据(如配置、用户信息)
  • 高并发场景(如电商商品详情页)
  • 计算成本高的操作(如复杂查询、API 调用)

通过合理的配置(refreshAfterWrite + expireAfterWrite)和最佳实践(防穿透、防雪崩),可以极大提升系统性能。

推荐组合

  • 单机应用:纯 Caffeine
  • 分布式系统:Caffeine + Redis(多级缓存)

附录:官方资源

  • GitHub: Caffeine
  • Spring Cache + Caffeine

希望这篇深度解析能帮助你掌握 Caffeine 的核心机制和最佳实践! 🚀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/910503.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/910503.shtml
英文地址,请注明出处:http://en.pswp.cn/news/910503.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

创客匠人赋能创始人 IP 打造:健康行业知识变现案例深度解析

在知识服务行业蓬勃发展的当下&#xff0c;创始人 IP 打造已成为知识变现的核心驱动力。创客匠人近期披露的陪跑案例显示&#xff0c;通过系统化的线上线下联动运营&#xff0c;传统行业从业者可高效实现 IP 价值转化。以亓黄中医科技创始人吴丰言老师为例&#xff0c;其在创客…

64、最小路径和

题目&#xff1a; 解答&#xff1a; 简单dp。 定义&#xff1a;dp[i][j]为到达(i,j)所需要的最短路程 初始化&#xff1a;dp[0][0]grid[0][0]&#xff0c;同时对第一行和第一列的&#xff0c;第i个就是前i个之和加上自身 递归&#xff1a;dp[i][j]min(dp[i-1][j],dp[i][j-1…

获取连接通义千问大语言模型配置信息的步骤:api_key、api_url

一、注册并开通通义千问API服务 1. 注册阿里云账号 访问 阿里云官网点击右上角"免费注册"&#xff0c;按指引完成账号注册和实名认证 2. 开通通义千问API服务 进入 通义千问API产品页点击"立即开通"&#xff0c;按提示完成服务开通&#xff08;部分服务…

汽车加气站操作工考试题库含答案【最新】

1.天然气的主要成分是&#xff08;&#xff09;。 A. 乙烷 B. 乙烯 C. 甲烷 D. 乙炔 答案&#xff1a;C 2.CNG 加气站中&#xff0c;加气机的加气软管应&#xff08;&#xff09;进行检查。 A. 每天 B. 每周 C. 每月 D. 每季度 答案&#xff1a;A 3.储气罐的安全阀应&#xf…

显示任何结构的数组对象数据【向上自动滚动】

显示任何结构的数组对象数据 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>地图编辑软件 - 数…

GPIO模式详解

一、GPIO的八种模式 GPIO支持4种输入模式&#xff08;浮空输入、上拉输入、下拉输入、模拟输入&#xff09;和4种输出模式&#xff08;开漏输出、开漏复用输出、推挽输出、推挽复用输出&#xff09;。 GPIO_Mode_AIN模拟输入GPIO_Mode_IN_FLOATING浮空输入GPIO_Mode_IPD下拉输…

django rest_framework 自定义403 Forbidden错误页面

django本来有是可以很方便自定义HTTP错误页面的&#xff0c;网上资料一大把。核心是在项目的urls代码中增加handler403的定义&#xff0c;比如&#xff1a; handler403 "app.views.your_custom_view" 404&#xff0c;500都是一样的&#xff0c;重新定义handler404…

Kafka Streams架构深度解析:从并行处理到容错机制的全链路实践

在流处理技术领域&#xff0c;Kafka Streams以其轻量级架构与Kafka生态的深度整合能力脱颖而出。作为构建在Kafka生产者/消费者库之上的流处理框架&#xff0c;它通过利用Kafka原生的分区、副本与协调机制&#xff0c;实现了数据并行处理、分布式协调与容错能力的无缝集成。本文…

【嵌入式硬件实例】-555定时器控制舵机/伺服电机

555定时器控制舵机/伺服电机 文章目录 555定时器控制舵机/伺服电机1、555定时器介绍2、舵机/伺服电机介绍3、硬件准备与接线使用 555 定时器 IC 的伺服电机控制器和测试仪电路是一个简单的电路,可用于生成操作伺服电机所需的控制信号。该电路允许我们通过按下按钮手动驱动/控制…

国产麒麟 安装可视化数据库软件DBeaver(图解)

目录 ​​​​​​​​编辑DBeaver介绍 官网 通过强制使用 Ubuntu 模板来修复 add-apt-repository 重新添加 PPA 撤销更改&#xff08;可选&#xff09; 官网直接下载 DBeaver CE 下载好后安装软件 启动方式一 启动方式二 启动成功 在左侧右击新建连接 安装驱动 测…

线程池 JMM 内存模型

线程池 & JMM 内存模型 文章目录 线程池 & JMM 内存模型线程池线程池的创建ThreadPoolExecutor 七大参数饱和策略ExecutorService 提交线程任务对象执行的方法&#xff1a;ExecutorService 关闭线程池的方法&#xff1a;线程池最大线程数如何确定&#xff1f; volatile…

[论文阅读] 软件工程 + 教学 | 软件工程项目管理课程改革:从传统教学到以学生为中心的混合式学习实践

软件工程项目管理课程改革&#xff1a;从传统教学到以学生为中心的混合式学习实践 论文信息 arXiv:2506.14369 Agile and Student-Centred Teaching of Agile/Scrum Concepts Maria Spichkova Comments: Preprint. Accepted to the 29th International Conference on Knowledg…

Windows系统提示“mfc140u.dll丢失”?详细修复指南,一键恢复程序运行!

当你兴致勃勃地打开某个游戏或专业软件时&#xff0c;突然弹出一条错误提示——“MFC140u.dll丢失”&#xff0c;程序直接闪退&#xff0c;让人无比沮丧。别担心&#xff01;这个问题并不复杂&#xff0c;通常只需重新安装运行库或修复系统文件即可解决。本文将为你提供详细的修…

云XR(AR/VR)算力底座关键特征与技术路径

云XR&#xff08;AR/VR&#xff09;算力底座是支撑扩展现实技术规模化落地的核心基础设施&#xff0c;当前发展呈现以下关键特征与技术路径&#xff1a; 一、算力架构&#xff1a;云边端协同异构融合 分布式部署模式‌ 云端‌&#xff1a;承担高复杂度渲染与大数据处理&#x…

Android开发常用adb合集

Android开发常用adb合集 Android开发常用adb合集crash日志导出 Android开发常用adb合集 crash日志导出 bugreport: adb bugreportdropbox: adb shell dumpsys dropbox --print > desktop/full_dropbox_logs.txt

LTspice仿真4——exp指数函数波形

参数设置 Vinitial&#xff1a;初始电压值 Vpulsed&#xff1a;脉冲达到值 Rise Delay&#xff1a;上升延迟时间 Rise Tau&#xff1a;上升指数系数tau Fall Delay&#xff1a;下降延迟时间 Fall Tau&#xff1a;下降指数系数tau tau决定指数波形下降或者上升快慢&#x…

[Java 基础]集合框架

在 Java 中&#xff0c;我们经常需要存储和操作一组数据&#xff0c;而集合框架就是为此而生。它提供了一套统一的接口和类&#xff0c;帮助我们高效地管理各种数据集合。 常用的集合框架中的类只有 ArrayList、LinkedList、HashSet、HashMap 这 4 个&#xff0c;这些类的继承…

SQL关键字三分钟入门:WITH —— 公用表表达式让复杂查询更清晰

在实际的数据库开发和分析中&#xff0c;我们常常会遇到复杂的多层嵌套查询&#xff0c;这样的 SQL 语句不仅难以阅读&#xff0c;也容易出错。 这时候就需要使用一个非常实用又优雅的关键字 —— WITH&#xff01; 它可以帮助我们将复杂的子查询提取出来并命名&#xff0c;从…

要在 Linux 不联网服务器 上部署并运行 Gitee 上的 vue-vben-admin 项目,并且该项目使用的是 pnpm 管理依赖

目录 ✅ 目标&#xff1a;在不联网服务器中成功运行 vue-vben-admin &#x1f449; 你需要的最终环境&#xff1a; ✅ 场景&#xff1a;完全离线部署并运行开发/构建环境 &#x1f9f1; 步骤总览&#xff1a; &#x1f6e0; 详细操作流程 ✅ 第 1 步&#xff1a;联网机器准…

中国风国潮通用PPT模版

中国风答辩总结汇报类通用PPT模版&#xff0c;古风PPT通用模版&#xff0c;国学精品PPT模版&#xff0c;中国风韵PPT模版 中国风国潮通用PPT模版&#xff1a;https://pan.quark.cn/s/59cea717fe8d