Guava Cache
Guava Cache介绍
Guava是Google提供的一套Java工具包,而Guava Cache是一套非常完善的本地缓存机制(JVM缓
存)。
Guava cache的设计来源于CurrentHashMap,可以按照多种策略来清理存储在其中的缓存值且保持很
高的并发读写性能。
Guava Cache应用场景
本地缓存的应用场景:
- 对性能有非常高的要求
- 不经常变化
- 占用内存不大
- 有访问整个集合的需求
- 数据允许不时时一致
guava cache
- 高并发,不需要持久化
Guava Cache 的优势
- 缓存过期和淘汰机制
在GuavaCache中可以设置Key的过期时间,包括访问过期和创建过期
GuavaCache在缓存容量达到指定大小时,采用LRU的方式,将不常使用的键值从Cache中删除 - 并发处理能力
GuavaCache类似CurrentHashMap,是线程安全的。
提供了设置并发级别的api,使得缓存支持并发的写入和读取
采用分离锁机制,分离锁能够减小锁力度,提升并发能力
分离锁是分拆锁定,把一个集合看分成若干partition, 每个partiton一把锁。ConcurrentHashMap
就是分了16个区域,这16个区域之间是可以并发的。GuavaCache采用Segment做分区。 - 更新锁定
一般情况下,在缓存中查询某个key,如果不存在,则查源数据,并回填缓存。(Cache Aside
Pattern)
在高并发下会出现,多次查源并重复回填缓存,可能会造成源的宕机(DB),性能下降
GuavaCache可以在CacheLoader的load方法中加以控制,对同一个key,只让一个请求去读源并
回填缓存,其他请求阻塞等待。 - 集成数据源
一般我们在业务中操作缓存,都会操作缓存和数据源两部分
而GuavaCache的get可以集成数据源,在从缓存中读取不到时可以从数据源中读取数据并回填缓
存 - 监控缓存加载/命中情况
统计
Guava Cache创建方式
GuavaCache有两种创建方式:
CacheLoader和Callable callback
public class GuavaDemo {
public static void main(String args[]) throws Exception {
LoadingCache<String, Object> cache = CacheBuilder.newBuilder()
// 最大3个 //Cache中存储的对象,写入3秒后过期
.maximumSize(3).expireAfterWrite(3,
//记录命中率 失效通知
TimeUnit.SECONDS).recordStats().removalListener(new
RemovalListener<Object, Object>() {
public void onRemoval(RemovalNotification<Object, Object>
notification) {
System.out.println(notification.getKey() + ":" + notification.getCause());
}
}
.build(
new CacheLoader<String, Object>() {
@Override
public String load(String s) throws Exception {
return Constants.hm.get(s);
}
}
);
/*
初始化cache
*/
initCache(cache);
System.out.println(cache.size());
displayCache(cache);
System.out.println("=============================");
Thread.sleep(1000);
System.out.println(cache.getIfPresent("1"));
Thread.sleep(2500);
System.out.println("=============================");
displayCache(cache);
}
public static Object get(String key, LoadingCache cache) throws Exception {
Object value = cache.get(key, new Callable() {
@Override
public Object call() throws Exception {
Object v = Constants.hm.get(key);
//设置回缓存
cache.put(key, v);
return v;
}
});
return value;
}
public static void initCache(LoadingCache cache) throws Exception {
/*
前三条记录
*/
for (int i = 1; i <= 3; i++) {
cache.get(String.valueOf(i));
}
}
/**
* 获得当前缓存的记录
*
* @param cache
* @throws Exception
*/
public static void displayCache(LoadingCache cache) throws Exception {
Iterator its = cache.asMap().entrySet().iterator();
while (its.hasNext()) {
System.out.println(its.next().toString());
}
}
}
CacheLoader
在创建cache对象时,采用CacheLoader来获取数据,当缓存不存在时能够自动加载数据到缓存中。
public static final LoadingCache<String, List<Hot>> Cache = CacheBuilder.newBuilder().maximumSize(4).build(new CacheLoader<String, List<Hot>>() {
@Override
public List<Hot> load(String s) throws Exception {
return Collections.emptyList();
}
});
Callable Callback
public static Object get(String key,LoadingCache cache)throws Exception{
Object value=cache.get(key, new Callable() {
@Override
public Object call() throws Exception {
String v= Constants.hm.get(key);
//设置回缓存
cache.put(key,v);
return v;
}
});
return value;
}