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