Guava cache学习_数据

在官方的文档说明中,Guava Cache实现了三种加载缓存的方式:


1.LoadingCache在构建缓存的时候,使用build方法内部调用CacheLoader方法加载数据

2.在使用get方法的时候,如果缓存不存在该key或者key过期等,则调用get(K, Callable)方式加载数据;

3.直接调用put方法来放置缓存


Guava cache学习_数据_02



Guava cache学习_加载_03



自然先看下核心实现localCache

在实现上,LocalCache的并发策略和ConcurrentHashMap的并发策略一致,也是进行了分段,支持不同段的并发写入。

https://www.cnblogs.com/shoren/p/guava_cache.html


guava cache是一个本地缓存。有以下优点:

1.很好的封装了get、put操作,能够集成数据源。

一般我们在业务中操作缓存,都会操作缓存和数据源两部分。如:put数据时,先插入DB,再删除原来的缓存;ge数据时,先查缓存,命中则返回,没有命中时,需要查询DB,再把查询结果放入缓存中。 guava cache封装了这么多步骤,只需要调用一次get/put方法即可。

2.线程安全的缓存,与ConcurrentMap相似,但前者增加了更多的元素失效策略,后者只能显示的移除元素。

3.Guava Cache提供了三种基本的缓存回收方式:基于容量回收、定时回收和基于引用回收。定时回收有两种:按照写入时间,最早写入的最先回收;按照访问时间,最早访问的最早回收。

监控缓存加载/命中情况。


对于get(key, loader)方法流程:

1.对key做hash,找到存储的segment及数组table上的位置;

2.链表上查找entry,如果entry不为空,且value没有过期,则返回value,并刷新entry。

3.若链表上找不到entry,或者value已经过期,则调用lockedGetOrLoad。

4.锁住整个segment,遍历entry可能在的链表,查看数据是否存在是否过期,若存在则返回。若过期则删除(table,各种queue)。若不存在,则新建一个entry插入table。放开整个segment的锁。

5.锁住entry,调用loader的reload方法,从数据源加载数据,然后调用storeLoadedValue更新缓存。

6.storeLoadedValue时,锁住整个segment,将value设置到entry中,并设置相关数据(入写入/访问队列,加载/命中数据等)。


getAll(keys)方法:

1.循环调用get方法,从缓存中获取key对应的value。没有命中的记录下来。

2.如果有没有命中的key,调用loadAll(keys,loader)方法加载数据。

3.将加载的数据依次缓存,调用segment的put(K key, int hash, V value, boolean onlyIfAbsent)方法。

4.put时,锁住整个segment,将数据插入链表,更新统计数据。


put(key,value)方法:

1.对key做hash,找到segment的位置和table上的位置;

2.锁住整个segment,将数据插入链表,更新统计数据。

putAll(map) 循环调用put方法。


putIfAbsent(key, value) 缓存中,键值对不存在的时候才插入。


1.Ehcache支持持久化到本地磁盘,Guava不可以;

2.Ehcache有现成的集群解决方案,Guava没有。不过个人感觉比较鸡肋,对JVM级别的缓存来讲太重了;

3.Ehcache jar包庞大,Guava Cache只是Guava jar包中的工具之一,而且后者远远小于Ehcache;

4.两种缓存当缓存过期或者没有命中的时候都可以通过load接口重载数据,调用方式略有不同。两者的主要区别是Ehcache的缓存load的时候,允许用户返回null,而Guava Cache则不允许返回为null,因为Guava Cache是根据value的值是否为null来判断是否需要load,所以不允许返回为null,但是使用的时候可以使用空对象替换。不允许返回null是一个很好的考虑;

5.Ehcache有内存占用大小统计,Guava Cache没有,需要自己开发;

6.Ehcache在put缓存的时候,对K、V都做了包装,对GC有一定影响。


什么时候适用Ehcache、什么时候适用Guava cache?

首先,两者都是很成熟的JVM级别缓存,所以在绝大多数情况都是可以满足要求的。


适用Ehcache的情况

1.需要持久化持久化。使用持久化功能需要,缓存稳定,以免持久化的数据不准确影响结果。

2.有集群解决方案。


适用Guava cache的情况

Guava cache说简单点就是一个支持LRU的ConCurrentHashMap,它没有Ehcache那么多的各种特性,只是提供了增、删、改、查、刷新规则和时效规则设定等最基本的元素。做一个jar包中的一个功能之一,Guava cache极度简洁并能满足觉大部分人的要求。


总结

Ehcache有着全面的缓存特性,但是略重。Guava cache有最基本的缓存特性,很轻。大家根据具体情况选择使用。