Guava cache 介绍和简单使用

近期做了一个项目迁移工作,用到了 Guava cache 实现缓存功能

Guava cache 是 Google Guava 下的一个缓存模块
缓存分为本地缓存和远端缓存。Guava cache 则属于本地缓存,数据存储在 JVM 内存中

数据操作

一般在业务中操作数据时,都会操作缓存和数据源 (DB) 两部分

  • put 操作,先插入数据,再删除缓存;
  • get 操作,先查缓存,命中则返回,没有命中则查库,然后把结果放入缓存

Guava cache 的优势

  • 封装 get / put 操作,能集成数据源;
  • 实现了线程安全 (具体实现:与 CocurrentHashMap 类似,但是添加更多元素失效策略);
  • Guava Cache提供了三种基本的缓存回收方式:基于容量回收、定时回收和基于引用回收。定时回收有两种:按照写入时间,最早写入的最先回收;按照访问时间,最早访问的最早回收;
  • 监控缓存的 加载 / 命中 情况

和 Redis 相比

  • 因为应用和缓存在同一个进程内,请求缓存速度更加迅速
  • 单线程下 Guava cache 优于 Redis;并发下 Redis 读取时间下降较明显,Guava cache 影响不大
    过期清理机制
    项目达到过期时间后不会马上清除,会在写操作和读操作时顺带清理

Java 实例

  1. 在 pom.xml 中添加以下内容,引入 jar 包
1
2
3
4
5
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>19.0</version>
</dependency>
  1. 在代码中根据需求创建缓存对象
1
2
3
4
5
6
7
8
9
10
11
12
/**
* 缓存
*/
private LoadingCache<String, Map<String, String> cache = CacheBuilder
.newBuilder()
.refreshAfterWrite(EXPIRE_TIME_MINUTES, TimeUnit.MINUTES)
.build(new CacheLoader<String, Map<String, String>>() {
@Override
public Map<String, String> load(String key) {
return getFromDb();
}
});
  1. 获取缓存的方法

1
cache.getUnchecked("");

加载机制

CacheLoader

从 LoadingCache 查询缓存的正规方法是 get(key) 方法,要么返回已经缓存的值,要么使用 CacheLoader 向缓存原子地添加新值

Callable

如果没有合理的默认方法来加载或计算与键关联的值,或者想要覆盖默认的加载运算,同时保留“获取缓存-如果没有-则计算”[get-if-absent-compute]的原子语义。
所有类型的Guava Cache,不管有没有自动加载功能,都支持get(K, Callable)方法。这个方法实现的是,如果有缓存,返回相应的值;如果缓存不存在,用给定的 Callable 运算把结果加入到缓存

Cache.put

cache.put(key, value) 可以直接向缓存中插入值,会覆盖掉 key 之前映射的 value

参考

Guava cache 使用总结
Guava cache 和 Redis 性能对比
Google Guava Cache 全解析