大廠都在用的本地緩存Ehcache原來這麼強!


  點擊上方“JavaEdge”,關注公衆號

設爲“星標”,好文章不錯過!


最爲廣泛使用的純Java開發的輕量級本地緩存框架。

Ehcache架構圖

核心組件

  • cache manager
    緩存管理器,可多實例

  • cache

    緩存管理器內可放置若干個cache,所有cache都實現了Ehcache接口,是實際使用的緩存實例,真正地存放數據通過緩存管理器模式,即可實現在單應用中隔離多個緩存實例,各自獨立服務不同業務場景,緩存數據物理隔離,同時需要時又可組合共享。

  • element

    單條緩存數據的組成單位。

  • system of record(SOR)

    實際緩存數據都是通過SOR讀寫的,可以是真正的業務邏輯、外部接口調用、存放真實數據的DB。

它的緩存介質涵蓋堆內存(heap)、堆外內存(BigMemory商用版本支持)和磁盤,各介質可獨立設置屬性和策略。
Ehcache最初是獨立的本地緩存框架,隨着發展,結合Terracotta服務陣列模型,可支持分佈式緩存集羣,主要有RMI、JGroups、JMS和Cache Server等傳播方式進行節點間通信,如架構圖左側部分。

數據流轉

  • Flush
    緩存條目向低層次移動

  • Fault

    從低層拷貝一個對象到高層。在獲取緩存的過程中,某層發現自己的該緩存數據已失效,就觸發Fault。

  • Eviction

    把緩存項除去

  • Expiration

    失效狀態

  • Pinning

    強制緩存項保持在某層

數據流轉生命週期

L1:本地內存層,L2:Terracotta服務節點層

配置

<ehcache><!-- 指定一個文件目錄,當Ehcache把數據寫到硬盤上時,將把數據寫到這個文件目錄下 --><diskStore path="java.io.tmpdir"/>
<!-- 設定緩存的默認數據過期策略 --><defaultCache maxElementsInMemory="10000" eternal="false" overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0" diskPersistent="false" diskExpiryThreadIntervalSeconds="120"/>
<!-- 設定具體的命名緩存的數據過期策略
cache元素的屬性: name:緩存名稱
maxElementsInMemory:內存中最大緩存對象數
maxElementsOnDisk:硬盤中最大緩存對象數,若是0表示無窮大
eternal:true表示對象永不過期,此時會忽略timeToIdleSeconds和timeToLiveSeconds屬性,默認爲false
overflowToDisk:true表示當內存緩存的對象數目達到了maxElementsInMemory界限後,會把溢出的對象寫到硬盤緩存中。注意:如果緩存的對象要寫入到硬盤中的話,則該對象必須實現了Serializable接口才行。
diskSpoolBufferSizeMB:磁盤緩存區大小,默認爲30MB。每個Cache都應該有自己的一個緩存區。
diskPersistent:是否緩存虛擬機重啓期數據
diskExpiryThreadIntervalSeconds:磁盤失效線程運行時間間隔,默認爲120秒
timeToIdleSeconds:設定允許對象處於空閒狀態的最長時間,以秒爲單位。當對象自從最近一次被訪問後,如果處於空閒狀態的時間超過了timeToIdleSeconds屬性值,這個對象就會過期,EHCache將把它從緩存中清空。只有當eternal屬性爲false,該屬性纔有效。如果該屬性值爲0,則表示對象可以無限期地處於空閒狀態
timeToLiveSeconds:設定對象允許存在於緩存中的最長時間,以秒爲單位。當對象自從被存放到緩存中後,如果處於緩存中的時間超過了 timeToLiveSeconds屬性值,這個對象就會過期,Ehcache將把它從緩存中清除。只有當eternal屬性爲false,該屬性纔有效。如果該屬性值爲0,則表示對象可以無限期地存在於緩存中。timeToLiveSeconds必須大於timeToIdleSeconds屬性,纔有意義
memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理內存。可選策略有:LRU(最近最少使用,默認策略)、FIFO(先進先出)、LFU(最少訪問次數)。--><cache name="CACHE1" maxElementsInMemory="1000" eternal="true" overflowToDisk="true"/>
<cache name="CACHE2" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="200" timeToLiveSeconds="4000" overflowToDisk="true"/></ehcache>

雖然Ehcache支持磁盤持久化,但由於存在兩級緩存介質。
在一級內存中的緩存,如果沒有主動刷入磁盤,應用異常時依然會出現緩存數據丟失。
可按需將緩存刷到磁盤,將緩存刷到磁盤的操作cache.flush()。
對象的磁盤寫入,前提是要將對象序列化。

特性

  • Ehcache的多線程機制專門高併發場景

  • 簡單

    小小的jar包,簡單配置開箱即用,單機場景更無需依賴其它組件

  • 多種緩存策略

  • 兩級存(內存&磁盤)

    相比一般本地緩存,有了磁盤,將可緩存更多數據

  • 監控

    具有緩存和緩存管理器的監聽接口,能更簡單方便的進行緩存實例的監控管理

  • 支持多緩存管理器實例,以及一個實例的多個緩存區域

  • 超時

    Ehcache的超時設置是針對整個cache實例的策略,而沒有提供方便的細粒度單獨key的超時處理。過期失效的緩存數據無法被GC回收,時間越長緩存越多,內存佔用越大,內存泄露概率越大

往期推薦



由於不知線程池的bug,某Java程序員叕被祭天

程序員因重複記錄日誌撐爆ELK被辭退!

擁抱Kubernetes,再見了Spring Cloud

雲原生時代下的網關V.S反向代理




目前交流羣已有 800+人,旨在促進技術交流,可關注公衆號添加筆者微信邀請進羣


喜歡文章,點個“在看、點贊、分享”素質三連支持一下~

本文分享自微信公衆號 - JavaEdge(Java-Edge)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章