Caffeine 是一个基于 Java 的高性能、现代化的缓存库。它由 Ben Manes 开发,受 Google Guava 缓存库的启发,但具有更好的性能和更多的功能。
Caffeine 的核心特点
-
高性能
- 基于 Java 8 的现代化设计,利用高级并发算法,提供极低的延迟和高吞吐量。
- 相比于 Guava Cache 和其他缓存库,Caffeine 在性能测试中表现出色。
-
灵活的缓存策略
- 支持多种缓存过期策略:
- 基于时间的过期(
expireAfterWrite
和expireAfterAccess
)。 - 基于大小的自动清除(
maximumSize
和maximumWeight
)。
- 基于时间的过期(
- 支持基于权重的缓存淘汰(需要自定义权重计算函数)。
- 支持多种缓存过期策略:
-
自适应淘汰策略
- 使用 Window TinyLFU 算法,该算法结合了频率和最近使用(LRU 和 LFU)的优点,能够更高效地淘汰缓存项。
-
强大的异步支持
- 提供异步缓存接口,可以异步加载缓存数据(
Caffeine.asyncCache
)。 - 特别适合高并发场景。
- 提供异步缓存接口,可以异步加载缓存数据(
-
完全可定制
- 提供丰富的 API,可根据需求灵活配置缓存行为。
- 支持监听器功能,可以监控缓存的命中率、缓存项的添加和移除。
-
与 Spring 的良好集成
- Caffeine 可以通过
spring-boot-starter-cache
与 Spring Cache 机制无缝集成,作为 Spring 的缓存提供者。
- Caffeine 可以通过
Caffeine 的基本用法
引入依赖
Maven:
xml
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
</dependency>
Gradle:
gradle
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'
创建缓存
同步缓存示例:
java
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
public class CaffeineExample {
public static void main(String[] args) {
// 配置缓存
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(100) // 最大条目数
.expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期
.build();
// 使用缓存
cache.put("key1", "value1");
String value = cache.getIfPresent("key1"); // 获取缓存项
System.out.println(value); // 输出: value1
}
}
异步缓存示例:
java
import com.github.benmanes.caffeine.cache.AsyncCache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class AsyncCaffeineExample {
public static void main(String[] args) {
// 配置异步缓存
AsyncCache<String, String> asyncCache = Caffeine.newBuilder()
.maximumSize(100)
.expireAfterWrite(10, TimeUnit.MINUTES)
.buildAsync();
// 异步加载
asyncCache.get("key1", key -> fetchFromDatabase(key)).thenAccept(value -> {
System.out.println("Loaded value: " + value);
});
}
// 模拟从数据库加载
private static String fetchFromDatabase(String key) {
return "FetchedValueFor-" + key;
}
}
常用 API
-
缓存大小和权重限制
javaCaffeine.newBuilder() .maximumSize(500) // 最大缓存条目数 .maximumWeight(1000) // 最大缓存权重(需指定权重函数) .weigher((key, value) -> value.toString().length()) // 权重函数 .build();
-
缓存过期策略
-
按时间过期:
javaCaffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期 .expireAfterAccess(5, TimeUnit.MINUTES) // 访问后5分钟过期 .build();
-
自定义过期:
javaCaffeine.newBuilder() .expireAfter(new Expiry<String, String>() { @Override public long expireAfterCreate(String key, String value, long currentTime) { return TimeUnit.MINUTES.toNanos(10); // 10分钟后过期 } @Override public long expireAfterUpdate(String key, String value, long currentTime, long currentDuration) { return currentDuration; // 不更新过期时间 } @Override public long expireAfterRead(String key, String value, long currentTime, long currentDuration) { return currentDuration; // 不更新过期时间 } }) .build();
-
-
统计信息
启用缓存统计,便于监控缓存命中率和性能:
javaCache<String, String> cache = Caffeine.newBuilder() .maximumSize(100) .recordStats() // 启用统计 .build(); System.out.println(cache.stats()); // 打印统计信息
-
监听器
注册监听器以捕获缓存项的添加、更新和移除事件:
javaCaffeine.newBuilder() .maximumSize(100) .removalListener((key, value, cause) -> System.out.printf("Key %s removed due to %s%n", key, cause)) .build();
适用场景
- API 调用结果缓存:减少重复的网络或服务调用。
- 数据查询缓存:缓存数据库查询结果,提升查询性能。
- 会话数据缓存:在用户访问期间缓存会话相关的数据。
- 实时性要求较高的应用:需要高效、低延迟的缓存系统。
与其他缓存库的比较
特性 | Caffeine | Guava Cache | Ehcache | Redis |
---|---|---|---|---|
本地缓存 | ✅ | ✅ | ✅ | ❌ |
分布式缓存 | ❌ | ❌ | ✅ | ✅ |
性能(低延迟) | 非常高 | 中等 | 中等 | 取决于网络 |
灵活性 | 高 | 中等 | 高 | 高 |
异步支持 | ✅ | ❌ | ❌ | ✅ |
总结
Caffeine 是一个高性能的本地缓存库,具有灵活的配置和优秀的性能表现,非常适合需要高效缓存的 Java 应用场景。如果你需要一个轻量级、高效的缓存解决方案,Caffeine 是一个绝佳的选择。