大廠都在用的本地緩存Ehcache原來這么強!
最為廣泛使用的純Java開發(fā)的輕量級本地緩存框架。
Ehcache架構(gòu)圖
核心組件
- cache manager
 
緩存管理器,可多實例
- cache
 
緩存管理器內(nèi)可放置若干個cache,所有cache都實現(xiàn)了Ehcache接口,是實際使用的緩存實例,真正地存放數(shù)據(jù)。通過緩存管理器模式,即可實現(xiàn)在單應(yīng)用中隔離多個緩存實例,各自獨立服務(wù)不同業(yè)務(wù)場景,緩存數(shù)據(jù)物理隔離,同時需要時又可組合共享。
- element
 
單條緩存數(shù)據(jù)的組成單位。
- system of record(SOR)
 
實際緩存數(shù)據(jù)都是通過SOR讀寫的,可以是真正的業(yè)務(wù)邏輯、外部接口調(diào)用、存放真實數(shù)據(jù)的DB。
它的緩存介質(zhì)涵蓋堆內(nèi)存(heap)、堆外內(nèi)存(BigMemory商用版本支持)和磁盤,各介質(zhì)可獨立設(shè)置屬性和策略。
Ehcache最初是獨立的本地緩存框架,隨著發(fā)展,結(jié)合Terracotta服務(wù)陣列模型,可支持分布式緩存集群,主要有RMI、JGroups、JMS和Cache Server等傳播方式進行節(jié)點間通信,如架構(gòu)圖左側(cè)部分。
數(shù)據(jù)流轉(zhuǎn)
- Flush
 
緩存條目向低層次移動
- Fault
 
從低層拷貝一個對象到高層。在獲取緩存的過程中,某層發(fā)現(xiàn)自己的該緩存數(shù)據(jù)已失效,就觸發(fā)Fault。
- Eviction
 
把緩存項除去
- Expiration
 
失效狀態(tài)
- Pinning
 
強制緩存項保持在某層
數(shù)據(jù)流轉(zhuǎn)生命周期
L1:本地內(nèi)存層,L2:Terracotta服務(wù)節(jié)點層
配置
- <ehcache>
 - <!-- 指定一個文件目錄,當(dāng)Ehcache把數(shù)據(jù)寫到硬盤上時,將把數(shù)據(jù)寫到這個文件目錄下 -->
 - <diskStore path="java.io.tmpdir"/>
 - <!-- 設(shè)定緩存的默認(rèn)數(shù)據(jù)過期策略 -->
 - <defaultCache
 - maxElementsInMemory="10000"
 - eternal="false"
 - overflowToDisk="true"
 - timeToIdleSeconds="0"
 - timeToLiveSeconds="0"
 - diskPersistent="false"
 - diskExpiryThreadIntervalSeconds="120"/>
 - <!--
 - 設(shè)定具體的命名緩存的數(shù)據(jù)過期策略
 - cache元素的屬性:
 - name:緩存名稱
 - maxElementsInMemory:內(nèi)存中最大緩存對象數(shù)
 - maxElementsOnDisk:硬盤中最大緩存對象數(shù),若是0表示無窮大
 - eternal:true表示對象永不過期,此時會忽略timeToIdleSeconds和timeToLiveSeconds屬性,默認(rèn)為false
 - overflowToDisk:true表示當(dāng)內(nèi)存緩存的對象數(shù)目達(dá)到了maxElementsInMemory界限后,會把溢出的對象寫到硬盤緩存中。注意:如果緩存的對象要寫入到硬盤中的話,則該對象必須實現(xiàn)了Serializable接口才行。
 - diskSpoolBufferSizeMB:磁盤緩存區(qū)大小,默認(rèn)為30MB。每個Cache都應(yīng)該有自己的一個緩存區(qū)。
 - diskPersistent:是否緩存虛擬機重啟期數(shù)據(jù)
 - diskExpiryThreadIntervalSeconds:磁盤失效線程運行時間間隔,默認(rèn)為120秒
 - timeToIdleSeconds:設(shè)定允許對象處于空閑狀態(tài)的最長時間,以秒為單位。當(dāng)對象自從最近一次被訪問后,如果處于空閑狀態(tài)的時間超過了timeToIdleSeconds屬性值,這個對象就會過期,EHCache將把它從緩存中清空。只有當(dāng)eternal屬性為false,該屬性才有效。如果該屬性值為0,則表示對象可以無限期地處于空閑狀態(tài)
 - timeToLiveSeconds:設(shè)定對象允許存在于緩存中的最長時間,以秒為單位。當(dāng)對象自從被存放到緩存中后,如果處于緩存中的時間超過了 timeToLiveSeconds屬性值,這個對象就會過期,Ehcache將把它從緩存中清除。只有當(dāng)eternal屬性為false,該屬性才有效。如果該屬性值為0,則表示對象可以無限期地存在于緩存中。timeToLiveSeconds必須大于timeToIdleSeconds屬性,才有意義
 - memoryStoreEvictionPolicy:當(dāng)達(dá)到maxElementsInMemory限制時,Ehcache將會根據(jù)指定的策略去清理內(nèi)存??蛇x策略有:LRU(最近最少使用,默認(rèn)策略)、FIFO(先進先出)、LFU(最少訪問次數(shù))。
 - -->
 - <cache name="CACHE1"
 - maxElementsInMemory="1000"
 - eternal="true"
 - overflowToDisk="true"/>
 - <cache name="CACHE2"
 - maxElementsInMemory="1000"
 - eternal="false"
 - timeToIdleSeconds="200"
 - timeToLiveSeconds="4000"
 - overflowToDisk="true"/>
 - </ehcache>
 
雖然Ehcache支持磁盤持久化,但由于存在兩級緩存介質(zhì)。
在一級內(nèi)存中的緩存,如果沒有主動刷入磁盤,應(yīng)用異常時依然會出現(xiàn)緩存數(shù)據(jù)丟失。
可按需將緩存刷到磁盤,將緩存刷到磁盤的操作cache.flush()。
對象的磁盤寫入,前提是要將對象序列化。
特性
- 快
 
Ehcache的多線程機制專門優(yōu)化高并發(fā)場景
- 簡單
 
小小的jar包,簡單配置開箱即用,單機場景更無需依賴其它組件
- 多種緩存策略
 - 兩級緩存(內(nèi)存&磁盤)
 - 相比一般本地緩存,有了磁盤,將可緩存更多數(shù)據(jù)
 - 監(jiān)控
 - 具有緩存和緩存管理器的監(jiān)聽接口,能更簡單方便的進行緩存實例的監(jiān)控管理
 - 支持多緩存管理器實例,以及一個實例的多個緩存區(qū)域
 - 超時
 
Ehcache的超時設(shè)置是針對整個cache實例的策略,而沒有提供方便的細(xì)粒度單獨key的超時處理。過期失效的緩存數(shù)據(jù)無法被GC回收,時間越長緩存越多,內(nèi)存占用越大,內(nèi)存泄露概率越大
本文轉(zhuǎn)載自微信公眾號「JavaEdge」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系JavaEdge公眾號。


















 
 
 













 
 
 
 