GuavaCache

Guava cache实现

数据结构 类似 1.7 ConcurrentHashMap,结构是 Segement 数组 + HashEntry数组 + 链表。

LRU算法实现 ConcurrentHashMap + 双向链表。

双向链表并不是全局的,而是每个Segement中都有。其中一共涉及到三个Queue其中包括:AccessQueue和WriteQueue,以及RecentQueue(基于性能考虑)。

Guava cache 回收机制

  • 基于容量回收:在缓存项的数目达到限定值之前,采用LRU的回收方式

  • 定时回收:expireAfterAccess,缓存项在给定时间内没有被读/写访问,则回收,回收顺序和基于大小回收一样(LRU);expireAfterWrite,缓存项在给定时间内没有被写访问(创建或覆盖),则回收

  • 基于引用回收:通过使用弱引用的键、或弱引用的值、或软引用的值,Guava Cache可以垃圾回收

每个entry会有个long accessTime 字段存储上一次访问时间,expireAfterAccess、expireAfterWrite 会在访问时查看是否过期,如果过期则重新load一次到本地缓存并返回。

关键参数

  • expireAfterWrite 当缓存项在指定的时间内没有更新就会被回收

  • expireAfterAccess 当缓存项在指定的时间内没有被读或写就会被回收

  • refreshAfterWrite 当缓存项上一次更新操作之后的多久会被刷新

  • concurrencyLevel 并发级别,使得缓存支持并发的写入和读取

refreshAfterWrite 特点是,在refresh的过程中,严格限制只有1个重新加载操作,而其他查询先返回旧值,这样有效地可以减少等待和锁争用。但不能严格保证所有的查询都获取到新值。

Guava cache 和分布式缓存比较

  1. 本地缓存没有网络开销,延时比分布式缓存更低

  2. 本地缓存有容量限制,分布式缓存可以扩容

  3. 应用重启本地缓存丢失,分布式缓存如redis有持久化机制

  4. 分布式缓存更复杂,需要考虑同步问题,本地缓存简单易实现

Last updated