Guava Cache
缓存分为本地缓存(进程内)和分布式缓存(独立服务)。Guava Cache 是 Google Guava 库提供的本地缓存实现,适合单机热点数据缓存;分布式缓存见 Redis。
基本用法
LoadingCache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) {
return "Hello: " + key;
}
});数据结构
核心数据结构类似 ConcurrentHashMap,使用分段锁提高并发性能。每个 Segment 继承 ReentrantLock,包含 ReferenceEntry 数组、引用队列和权重值统计。
put 操作流程
不同 Segment 可并发写入,同一 Segment 串行写入。
get 操作流程
public V get(Object key) {
int hash = hash(key);
return segmentFor(hash).get(key, hash);
}加载缓存时如果不存在,调用 CacheLoader.load(key) 自动加载。
淘汰策略
| 策略 | 说明 |
|---|---|
maximumSize | 基于容量淘汰 |
maximumWeight + weigher | 基于权重淘汰 |
expireAfterWrite | 写入后过期 |
expireAfterAccess | 访问后过期 |
refreshAfterWrite | 写入后刷新(配合 expire 使用) |
RemovalListener
监听缓存移除事件,可用于清理关联资源:
CacheBuilder.newBuilder()
.removalListener(RemovalListeners.asSynchronous(notification -> {
System.out.println("移除: " + notification.getKey());
}));与 ConcurrentHashMap 对比
| 特性 | Guava Cache | ConcurrentHashMap |
|---|---|---|
| 过期策略 | 支持 | 不支持 |
| 淘汰策略 | 支持 | 不支持 |
| 统计 | 支持 | 不支持 |
| 加载 | 支持(Loader) | 不支持 |
| 并发 | 分段锁 | CAS + 分段锁 |
Guava Cache 适合需要过期、淘汰、自动加载的缓存场景;纯 KV 高并发读写用 ConcurrentHashMap。
性能优化
- 合理设置并发度:默认 4,根据实际并发调整
- 避免大 value:增加内存压力和序列化成本
- 选择合适的淘汰策略:根据业务场景选择
- 使用弱引用:对于内存敏感场景
常见问题
Guava Cache 内存溢出
- 合理设置
maximumSize,避免缓存无限增长 - 使用
weakKeys()或weakValues()允许 GC 回收 - 监控缓存命中率,过低说明缓存策略不合理