天天看點

淺析本地緩存技術-Guava Cache

作者:京東雲開發者

1 引言

作為java開發工作者,相信大家對于guava這個工具包都不會太陌生,而對于本地緩存技術guava cache,大家在日常的工作開發中也都有所了解,接下來本文就從各個角度入手來對于Google提供的guava cache進行解析。

2 guava cache應用場景

本地緩存的資料讀寫都在一個程序内,相對與redis等分布式緩存,不需要網絡傳輸的過程,通路速度很快,同時也受到JVM記憶體的制約,無法在資料量較多的場景下使用。

基于以上特點,guava cache的主要應用場景為以下幾種:

  • 對于通路速度有較大要求
  • 存儲的資料不經常變化
  • 資料量不大,占用記憶體較小
  • 需要通路整個集合
  • 能夠容忍資料不是實時的

在這裡guava cache被用于儲存參數配置,也符合以上的應用場景條件。

淺析本地緩存技術-Guava Cache

3 guava cache的使用方式

guava cache位于com.google.common.cache包下,核心的類有兩個,一個是CacheBuilder,是用來建構緩存的,另一個是Cache,也就是緩存容器,用來存放緩存資料的。

要使用guava cache,首先要引入maven依賴:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>18.0</version>
</dependency>           

接下來寫一個簡單的示例:

Cache<String, String> localCache = CacheBuilder.newBuilder()
                .initialCapacity(5)
                .maximumSize(10)
                .concurrencyLevel(3)
                .expireAfterWrite(10, TimeUnit.SECONDS)
                .build();           

以上示例執行個體化了一個本地緩存,接下來介紹一下初始化的各項參數的含義:

initialCapacity:内部哈希表的最小容量,也就是cache的初始容量。

maximumSize:cache的最大緩存數。

concurrencyLevel:并發等級,也可以定義為同時操作緩存的線程數,由

淺析本地緩存技術-Guava Cache

可以看出,這個線程數預設為4。

expireAfterWrite:緩存寫入後重新整理時間。

從緩存中擷取資料調用的方法為get(K key, Callable<? extends V> loader)方法,此方法的含義是根據鍵key擷取資料,若key不存在,則通過執行指定的Callable方法來構造緩存,示例代碼如下所示:

Map<String, Dicdetail> dicDetailMap = ObLocateCache.locateConfigCache.get(key.toString(), new Callable<Map<String, Dicdetail>>() {
                @Override
                public Map<String, Dicdetail> call() throws Exception {
                    return getConfigParameterFromMaster(baseDomain, KeyConstants.WMS5_LOCATE_MANUAL);
                }
            });           

從cache中删除資料分為被動删除和主動删除兩種:

1.被動删除:

  • 基于資料大小删除:LRU+FIFO
  • 基于過期時間删除:在指定時間内沒有被通路
  • 基于引用删除:通過weakKeys和weakValues方法指定Cache隻儲存對緩存記錄key和value的弱引用。這樣當沒有其他強引用指向key和value時,key和value對象就會被垃圾回收器回收

2.主動删除:

//删除指定的key對應資料
cache.invalidate("s");
//将一批對應的資料删除
cache.invalidateAll(Arrays.asList("st","r","ing"));
//全部删除
cache.invalidateAll();           

4 根據源碼分析guava cache的存儲原理

guava cache的資料結構跟ConcurrentHashMap類似,二者最基本的差別是ConcurrentMap會一直儲存所有添加的元素,直至将添加的元素移除。相對地,guava cache為了限制記憶體占用,通常都設定為自動回收元素。

guava cache的核心類為LocalCache,LocalCache實作了ConcurrentMap接口。其中有一個Segment數組,如下所示

淺析本地緩存技術-Guava Cache

擷取資料的方法源碼如下圖所示,可以看出guava cache的存儲原理為由Segment數組加上ReferenceEntry連結清單加上AtomicReferenceArray數組組成的資料結構。

淺析本地緩存技術-Guava Cache
淺析本地緩存技術-Guava Cache
淺析本地緩存技術-Guava Cache

資料結構圖如下所示:

淺析本地緩存技術-Guava Cache

Segement數組的長度決定了cache的并發數。每一個Segment都繼承了ReentrantLock,使用了單獨的鎖,對Segment的寫操作需要先拿到鎖。寫操作部分源碼如下所示:

淺析本地緩存技術-Guava Cache
淺析本地緩存技術-Guava Cache

5 總結

本文簡要叙述了guava cache的應用場景以及簡單的使用方式,通過源碼對于guava cache的存儲原理以及簡單的讀寫方法進行了介紹。相信通過閱讀本文,能夠對于常見的guava cache有一個大緻的認知。

作者:京東物流 王辰玮

來源:京東雲開發者社群 自猿其說Tech

繼續閱讀