喻轩Blog - Guava
type: channel
link: https://blog.yuxuan.io/tags/guava
items: Guava Cache

Guava Cache
type: item
date: 2020-10-09T10:35:16+08:00
description: Guava Cache介绍JVM缓存JVM 缓存，是堆缓存。其实就是创建一些全局容器，比如List、Set、Map等，这些容器用来做数据存储。这样做的问题：不能按照一定的规则淘汰数据，如 LRU，LFU，FIFO 等。没有清除数据时的回调通知并发处理能力差，针对并发可以使用CurrentHashMap，但缓存的其他功能需要自行实现缓存过期处理，缓存数据加载刷新等都需要手工实现Guava CacheGuava是Google提供的一套Java工具包，而Guava Cache是一套非常完善的本地缓存机制（JVM缓存）。Guava cache的设计来源于CurrentHashMap，可以按照多种策略来清理存储在其中的缓存值且保持很高的并发读写性能。Guava Cache应用场景本地缓存的应用场景：对性能有非常高的要求不经常变化占用内存不大有访问整个集合的需求数据允许不时时一致guava cache高并发，不需要持久化currentHashMap高并发Ehcached持久化 二级缓存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 callbackpublic class GuavaDemo { public static void main(String args[]) throws Exception { LoadingCache<String,Object> cache = CacheBuilder.newBuilder() // 最大3个 .maximumSize(3) //Cache中存储的对象,写入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 Objec…