在后端系统中,缓存是提升性能的关键手段,但并非所有场景都适合引入 Redis 这类分布式缓存 —— 对于本地高频访问的小数据(如配置信息、字典表),Guava 缓存凭借轻量级、零部署成本的优势,成为更优选择。它就像一把 “瑞士军刀”,小巧灵活却能解决不少实际问题。
Guava 缓存是什么?
Guava 是 Google 开源的 Java 工具库,其中的Cache模块提供了基于内存的本地缓存实现,支持过期策略、最大容量限制、缓存加载机制等核心功能。与 HashMap 相比,它多了自动过期、淘汰策略和统计监控能力;与 Redis 相比,它省去了网络开销,适合单机场景的临时缓存。
核心特性与使用场景
1. 自动过期与淘汰机制
Guava 缓存支持两种过期策略:
-
写入过期(
expireAfterWrite):数据写入后多久过期(如商品详情缓存 10 分钟) -
访问过期(
expireAfterAccess):数据最后一次访问后多久过期(如用户会话缓存)
还支持基于容量的淘汰(maximumSize),当缓存条目数超过限制时,自动删除最少使用(LRU)的条目。
代码示例:
LoadingCache<String, Product> productCache = CacheBuilder.newBuilder()
.maximumSize(1000) // 最大缓存1000条
.expireAfterWrite(10, TimeUnit.MINUTES) // 写入后10分钟过期
.recordStats() // 开启统计
.build(new CacheLoader<String, Product>() {
// 缓存不存在时加载数据(自动触发)
@Override
public Product load(String productId) throws Exception {
return productDao.getById(productId); // 从数据库加载
}
});
// 使用缓存
try {
Product product = productCache.get("1001"); // 存在则返回缓存,否则调用load方法
} catch (ExecutionException e) {
// 处理加载失败
}
2. 缓存刷新与预热
- 主动刷新:通过
refresh(key)方法触发缓存更新,刷新过程中仍返回旧值(避免阻塞) - 缓存预热:系统启动时主动加载热点数据到缓存,如首页推荐商品,减少首次访问的加载延迟
3. 统计监控
开启recordStats()后,可通过stats()方法获取缓存命中率、加载时间等指标,帮助优化缓存策略:
CacheStats stats = productCache.stats();
double hitRate = stats.hitRate(); // 命中率(越高越好)
long averageLoadTime = stats.averageLoadPenalty(); // 平均加载时
避坑指南
- 不适合存储大量数据:本地缓存占用 JVM 内存,过大可能导致 OOM,建议单实例缓存不超过 10 万条
- 注意线程安全:
get()方法是线程安全的,但自定义load方法需确保线程安全 - 避免缓存雪崩:本地缓存无分布式协调机制,多实例同时失效可能压垮数据库,建议过期时间加随机偏移量