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

简单高效的缓存解决方案--Guava Cache

目录
  • 简单高效的缓存解决方案--Guava Cache
    • 什么是 Guava Cache?
    • 核心优势
      • 1. 自动驱逐策略
      • 2. 时间-based 过期
      • 3. 自动加载数据
    • 实战示例
      • 1. 配置缓存实例
      • 2. 批量操作
      • 3. 缓存统计与监控
    • 高级特性
      • 1. 缓存刷新
      • 2. 移除监听器
      • 3. 异步刷新
    • 最佳实践
      • 1. 合理设置缓存大小
      • 2. 处理加载异常
      • 3. 结合 Spring 使用
    • 性能考虑
      • 1. 选择合适的驱逐策略
      • 2. 监控与调优
    • 总结

简单高效的缓存解决方案--Guava Cache

在构建高性能Java应用时,缓存是提升系统性能的关键技术之一。虽然 ConcurrentHashMap 能够提供基础的键值存储,但在实际的缓存场景中,我们往往需要更多专业特性。这就是 com.google.common.cache 大显身手的地方。

什么是 Guava Cache?

Guava Cache 是 Google Guava 库中的一个本地缓存实现,它提供了比普通 Map 更丰富的缓存特性,包括自动驱逐、过期策略、统计信息等,专门为缓存场景深度优化。

Guava Cache 是超越普通Map的高性能本地缓存。

从本质上讲,它确实就是一个 Map

但更准确地说,它是一个「智能的、自带管理功能的 Map」

<dependencies><!-- Guava 核心依赖 --><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>32.1.3-jre</version><!-- 或者使用 Android 版本 --><!-- <version>32.1.3-android</version> --></dependency>
</dependencies>

核心优势

1. 自动驱逐策略

普通 Map 需要手动管理内存,而 Guava Cache 提供了多种自动驱逐机制:

// 基于大小的驱逐
Cache<String, Object> sizeBasedCache = CacheBuilder.newBuilder().maximumSize(1000) // 最多1000个条目.build();// 基于权重的驱逐
Cache<String, Object> weightBasedCache = CacheBuilder.newBuilder().maximumWeight(1000000) // 总权重最大100万.weigher((String key, Object value) -> getWeight(value)).build();

2. 时间-based 过期

Cache<String, Object> timeBasedCache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES)  // 写入后10分钟过期.expireAfterAccess(5, TimeUnit.MINUTES)  // 5分钟未被访问则过期.build();

3. 自动加载数据

最强大的特性之一:当缓存未命中时自动加载数据。

LoadingCache<String, User> userCache = CacheBuilder.newBuilder().maximumSize(1000).build(new CacheLoader<String, User>() {@Overridepublic User load(String userId) throws Exception {// 当缓存不存在时,自动调用此方法加载数据return userService.getUserById(userId);}});// 使用 - 如果不存在会自动加载
User user = userCache.get("123");

实战示例

1. 配置缓存实例

public class ProductCache {private final LoadingCache<String, Product> cache;public ProductCache(ProductService productService) {this.cache = CacheBuilder.newBuilder().maximumSize(500).expireAfterWrite(30, TimeUnit.MINUTES).refreshAfterWrite(10, TimeUnit.MINUTES) // 定时刷新.recordStats() // 开启统计.build(new CacheLoader<String, Product>() {@Overridepublic Product load(String productId) {return productService.getProduct(productId);}@Overridepublic ListenableFuture<Product> reload(String key, Product oldValue) {// 异步刷新return productService.getProductAsync(key);}});}public Product getProduct(String productId) {try {return cache.get(productId);} catch (ExecutionException e) {throw new RuntimeException("Failed to load product: " + productId, e);}}
}

2. 批量操作

// 批量获取
Map<String, User> users = userCache.getAll(Arrays.asList("1", "2", "3"));// 批量失效
cache.invalidateAll(Arrays.asList("key1", "key2"));// 清空缓存
cache.invalidateAll();

3. 缓存统计与监控

CacheStats stats = cache.stats();logger.info("缓存命中率: {}%", stats.hitRate() * 100);
logger.info("平均加载时间: {}ms", stats.averageLoadPenalty() / 1000000);
logger.info("缓存命中次数: {}", stats.hitCount());
logger.info("缓存未命中次数: {}", stats.missCount());
logger.info("驱逐次数: {}", stats.evictionCount());

高级特性

1. 缓存刷新

LoadingCache<String, Config> configCache = CacheBuilder.newBuilder().refreshAfterWrite(1, TimeUnit.MINUTES) // 1分钟后刷新.build(new CacheLoader<String, Config>() {@Overridepublic Config load(String key) {return loadConfig(key);}});

2. 移除监听器

Cache<String, Data> cache = CacheBuilder.newBuilder().removalListener((RemovalNotification<String, Data> notification) -> {RemovalCause cause = notification.getCause();String key = notification.getKey();Data value = notification.getValue();logger.info("Key {} 被移除,原因: {}", key, cause);if (cause == RemovalCause.SIZE) {// 处理因大小限制被移除的情况metrics.recordEviction();}}).build();

3. 异步刷新

LoadingCache<String, HeavyObject> asyncCache = CacheBuilder.newBuilder().refreshAfterWrite(10, TimeUnit.MINUTES).build(CacheLoader.asyncReloading(new CacheLoader<String, HeavyObject>() {@Overridepublic HeavyObject load(String key) {return computeHeavyObject(key);}}, executorService // 使用线程池异步刷新));

最佳实践

1. 合理设置缓存大小

// 根据应用内存情况设置合理的大小
CacheBuilder.newBuilder().maximumSize(calculateOptimalSize()) // 动态计算.build();

2. 处理加载异常

LoadingCache<String, Data> safeCache = CacheBuilder.newBuilder().build(new CacheLoader<String, Data>() {@Overridepublic Data load(String key) throws Exception {try {return externalService.getData(key);} catch (Exception e) {// 返回默认值或抛出特定异常return getDefaultData();}}});

3. 结合 Spring 使用

@Component
public class CacheManager {@Autowiredprivate UserRepository userRepository;private LoadingCache<Long, User> userCache;@PostConstructpublic void init() {userCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(2, TimeUnit.HOURS).recordStats().build(CacheLoader.from(userRepository::findById));}public User getUser(Long id) {try {return userCache.get(id);} catch (ExecutionException e) {throw new RuntimeException("Cache load failed", e);}}
}

性能考虑

1. 选择合适的驱逐策略

  • maximumSize(): 适用于条目大小相近的场景
  • maximumWeight(): 适用于条目大小差异较大的场景
  • expireAfterWrite(): 适用于数据不经常变化的场景
  • expireAfterAccess(): 适用于需要保留热门数据的场景

2. 监控与调优

// 定期输出缓存统计
scheduledExecutorService.scheduleAtFixedRate(() -> {CacheStats stats = cache.stats();if (stats.requestCount() > 0) {logger.info("缓存统计: 命中率={}%, 加载次数={}, 平均加载时间={}ms",String.format("%.2f", stats.hitRate() * 100),stats.loadCount(),String.format("%.2f", stats.averageLoadPenalty() / 1000000.0));}
}, 1, 1, TimeUnit.MINUTES);

总结

Guava Cache 提供了一个功能完整、性能优异的本地缓存解决方案。与普通 Map 相比,它在以下方面表现出色:

  • 自动内存管理 - 无需手动清理
  • 灵活的过期策略 - 时间和访问频率控制
  • 丰富的统计信息 - 便于监控和调优
  • 线程安全 - 内置并发控制
  • 自动加载 - 简化缓存未命中处理

对于大多数Java应用的本地缓存需求,Guava Cache 都是一个值得信赖的选择。它既保持了使用的简洁性,又提供了企业级缓存所需的强大功能。

适用场景:数据量不大、访问频繁、计算成本高的数据缓存,如配置信息、用户会话、数据库查询结果等。

不适用场景:分布式环境、超大容量缓存(考虑 Redis 等分布式缓存)。

http://www.jsqmd.com/news/43441/

相关文章:

  • 2025年柱状活性炭实力厂家权威推荐榜单:中水回用活性炭/压块破碎活性炭/活性炭源头厂家精选
  • 基于Dify工作流与Jira API构建自优化测试系统
  • 2025 年 10 月科技前沿全景:从量子跃迁到生命重构的文明拐点 - 实践
  • 传统化工企业的 “能耗死循环”:MyEMS 如何用 “数据中台” 打通设备孤岛?
  • 2025年苗木批发基地实力批发商排行榜全新发布,丝棉木/红叶石楠/苗木/红叶李/国槐/青叶复叶槭/紫薇/油松/白蜡/金叶女贞/栾树种植哪家好
  • 2025年11月国内矿山设备检测检验公司权威推荐榜单:专业选择指南
  • 2025年国内矿山设备检测检验公司十大权威推荐榜单
  • 2025留学机构哪家比较好一点
  • 2025杭州最大留学中介机构在哪里
  • 2025出国留学机构排名对比图
  • 2025成都留学中介推荐
  • 2025年本地人推荐口碑好的火锅哪家好吃,社区火锅/烧菜火锅/老火锅/火锅店/美食/火锅/特色美食回头客多的推荐
  • JSAPIThree之Bloom 效果学习笔记:让我的 3D 场景发光发亮!
  • 查看当前 Java 运行的版本?
  • webman是异步非阻塞的,这个是指在处理接口请求的时候么,那如果接口程序中,有外部的请求或者读写数据库即IO开销,那这个是异步非阻塞的么 goframe又是怎样的
  • 浅显易懂的解释一下RRF加权算法的意思
  • RabbitMQ 在 Windows 下频繁出现 “vhost / is down” 与 Mnesia 损坏问题的完整排查与解决方案
  • 实用指南:用 FPGA 实现 PCIe 传输,开源核 LitePCIe 深度解读
  • 2025年东莞大小泥水工程公司权威推荐榜单:洁净房设计/修缮工程/钢构工程施工源头公司精选
  • linux 4.6
  • 20、查询MySQL网络配置
  • linux 3g驱动
  • linux 3g上网卡
  • 批量处理工具类 用于解决大批量数据操作时的数据库性能问题
  • 2025年11月领导品牌认证机构推荐榜:权威机构对比与选择指南
  • 2025年11月人形机器人落地商推荐排行榜:基于多维度数据分析的权威榜单
  • 随机爬树题解
  • 2025年11月四川护栏厂家推荐榜:综合实力与用户口碑全面对比
  • 2025年11月人形机器人落地商排行推荐:中立评价与场景适配
  • 2025年11月四川护栏厂家推荐榜单:基于用户需求的权威对比与选择指南