在 Java 后端开发中,本地缓存(Local Cache) 是非常常见的性能优化手段。

当系统频繁访问数据库或远程服务时,可以通过缓存减少 IO 开销,提高系统吞吐量。

在 Java 生态中,最常见的本地缓存方案主要有两个:

Guava Cache   Caffeine

很多面试中也经常会问:

  • Guava Cache 和 Caffeine 有什么区别?

  • 为什么现在很多项目更推荐使用 Caffeine?

  • Caffeine 为什么性能更高?

本文带你系统了解 Guava Cache 和 Caffeine 的原理与区别


一、本地缓存是什么

本地缓存(Local Cache) 指的是将数据缓存在 应用进程的 JVM 内存中

典型访问流程:

请求 → 本地缓存 → Redis / 数据库

如果缓存命中,就可以直接返回数据,从而避免访问数据库。

优点

  • 访问速度极快(内存级)

  • 减少数据库压力

  • 降低系统延迟

缺点

  • 只在当前 JVM 内有效

  • 多实例部署时缓存不共享

因此本地缓存通常用于:热点数据缓存、配置缓存、读多写少的数据


二、Guava Cache 简介

Guava Cache 是 Google 在 Guava 工具库中提供的一个本地缓存实现。

它提供了一套非常简单易用的缓存 API。

基本使用

Cache<String, String> cache = CacheBuilder.newBuilder()
        .maximumSize(1000)
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .build();

cache.put("key", "value");

String value = cache.getIfPresent("key");

Guava Cache 常见特性

1 自动加载

可以使用 LoadingCache 实现自动加载。

LoadingCache<String, String> cache = CacheBuilder.newBuilder()
        .maximumSize(1000)
        .build(new CacheLoader<String, String>() {
            @Override
            public String load(String key) {
                return loadFromDb(key);
            }
        });

String value = cache.get("key");

当缓存不存在时,会自动调用 load() 方法加载数据。


2 过期策略

Guava 支持两种常见过期策略:

  • expireAfterWrite:写入后过期

  • expireAfterAccess:访问后过期


3 缓存大小限制

可以通过 maximumSize 限制缓存最大数量,防止缓存无限增长。


4 移除监听

Guava 支持缓存移除监听:

.removalListener(notification -> {
    System.out.println("key removed: " + notification.getKey());
})

当缓存被淘汰或过期时,可以执行回调逻辑。


三、Guava Cache 的问题

虽然 Guava Cache 非常好用,但在高并发场景下也暴露了一些问题。

1 锁竞争问题

Guava Cache 使用 Segment 分段锁机制

在高并发情况下容易出现:

  • 线程竞争锁

  • 性能下降


2 淘汰算法较简单

Guava 使用的是 LRU 近似算法

只考虑最近访问时间,没有考虑访问频率,因此命中率并不是最优。


3 官方不再持续优化

Guava Cache 目前基本进入 维护状态

很多新项目已经转向使用 Caffeine


四、Caffeine 简介

Caffeine 是 Guava Cache 作者 Ben Manes 重新设计的一款高性能本地缓存库。

GitHub 地址:

https://github.com/ben-manes/caffeine

Caffeine 的目标是:构建 Java 中性能最好的本地缓存库。

在官方 Benchmark 中,Caffeine 的性能通常是 Guava Cache 的数倍


五、Caffeine 基本使用

Caffeine 的 API 与 Guava 非常类似,因此迁移成本非常低。

基础示例

Cache<String, String> cache = Caffeine.newBuilder()
        .maximumSize(1000)
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .build();

cache.put("key", "value");

String value = cache.getIfPresent("key");

自动加载

LoadingCache<String, String> cache = Caffeine.newBuilder()
        .maximumSize(1000)
        .build(key -> loadFromDb(key));

String value = cache.get("key");

异步缓存

Caffeine 支持 异步加载缓存

AsyncLoadingCache<String, String> cache =
        Caffeine.newBuilder()
                .maximumSize(1000)
                .buildAsync(key -> loadFromDb(key));

适用于:

  • RPC 请求

  • IO 密集型任务

  • 远程接口调用


六、Caffeine 为什么这么快

1 W-TinyLFU 淘汰算法

传统缓存淘汰算法:

算法 特点
FIFO 不考虑访问频率
LRU 只考虑最近访问
LFU 统计成本高

Caffeine 使用 W-TinyLFU(Window TinyLFU)

核心思想:

结合 LRU + LFU

策略:

  1. 新数据先进入 Window 区(LRU)

  2. 高频访问数据进入 Main 区(LFU)

  3. 淘汰低频数据

这样可以显著提升缓存命中率。


2 无锁读设计

Guava 使用 Segment Lock

而 Caffeine 使用:

  • CAS

  • 无锁数据结构

因此可以减少锁竞争,在高并发环境下性能更好。


3 高效数据结构

Caffeine 内部使用了多种高性能结构,例如:

  • RingBuffer

  • ConcurrentHashMap

  • CAS 原子操作

从而保证高并发下依然保持高性能。


七、Guava Cache vs Caffeine

对比 Guava Cache Caffeine
发布时间 较早 较新
并发性能 一般 很高
淘汰算法 LRU W-TinyLFU
锁机制 Segment Lock CAS + 无锁
异步支持 不支持 支持
官方推荐 维护状态 推荐使用

总结一句话:

Caffeine 可以看作 Guava Cache 的升级版。


八、Spring Boot 中使用 Caffeine

Spring Boot 对 Caffeine 有官方支持。

引入依赖:

<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
</dependency>

配置 CacheManager

@Bean
public CacheManager cacheManager() {
    CaffeineCacheManager manager = new CaffeineCacheManager();
    manager.setCaffeine(Caffeine.newBuilder()
            .maximumSize(1000)
            .expireAfterWrite(10, TimeUnit.MINUTES));
    return manager;
}

使用缓存:

@Cacheable("user")
public User getUser(Long id) {
    return userMapper.selectById(id);
}

九、常见应用场景

Caffeine 在实际项目中常见的使用场景包括:

1 热点数据缓存

例如:用户信息、商品信息、系统配置


2 本地缓存 + Redis 多级缓存

常见架构:

请求 → Caffeine → Redis → 数据库

这样可以:减少 Redis 压力和降低访问延迟


3 防止缓存击穿

对于热点 Key,可以先使用本地缓存挡住大量请求。


十、总结

Guava Cache 和 Caffeine 都是 Java 常用的本地缓存库。

但随着高并发场景的增多:

Caffeine 已经逐渐成为主流选择。

主要原因包括:

  • 更高并发性能

  • 更先进的淘汰算法

  • 更丰富的功能(异步缓存)

因此在新项目中,一般推荐直接使用 Caffeine


如果这篇文章对你有帮助,欢迎点个赞 👍
后续会持续更新 Java 后端高频技术解析系列

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐