1.Overview
Ehcache從 Hibernate 發展而來,逐漸涵蓋了Cahce界的全部功能,是目前發展勢頭最好的一個項目。
標准緩存
分布式緩存(基於RMI/JGroups/JMS)
URL,頁面片段緩存(類似OSCache的相關部分)
中央緩存服務器(類似Memcached)
2.基本功能與配置
Ehcache的基本功能,可以從配置文件中學習。
總的來說,緩存與HashMap的最大不同,就是緩存設想內存是有限的,緩存的時效性也是有限的,所以可以設定內存數量的大小,可以執行失效算法 ,可以在內存滿了的時候,按照最少訪問等算法將緩存直接移除或切換到硬盤上。
另外注意,ehcache的CacheManager本身有一定的默認值。而在沒有指定ehcache.xml的情況下, 會使用ehcache.jar裡自帶的ehcache_failsafe.xml,
2.1 對象在內存中的最大數量
因為內存是有限的,所以必須用maxElementsInMemory(必填項)設置每類對象在內存中的最大數量。ehcache_failsafe.xml 中為10000。
2.2 到達內存中最大量時的過期/移出算法
過期算法: 如果緩存已經失效,人道毀滅之。失效算法由3個參數組成:
eternal(必填項):如果為true,則永不過期,忽略後兩個參數的設置。ehcache_failsafe.xml 為false.
timeToIdleSeconds: 空閒無訪問時間,默認為0,永不過時。ehcache_failsafe.xml 設為120秒。
timeToLiveSeconds: 空閒無訪問時間,默認為0,永不過時。ehcache_failsafe.xml 設為120秒。
移出算法:如果經過失效算法後,還是有很多有效的緩存,則執行清除算法。清除算法由兩個參數組成:
memoryStoreEvictionPolicy: 默認為LRU(最近最少訪問),另有先進先出(FIFO),最少訪問次數(LFU)
overflowToDisk(必填項) 為true,則將清除出來的緩存持久化到磁盤,否則人道毀滅之。
2.3 儲存到硬盤
maxElementsOnDisk,默認為0,無限多。ehcache_failsafe.xml為10000000。
diskExpiryThreadIntervalSeconds:使用過期算法清除磁盤中失效對象的間隔,默認為120秒。
diskSpoolBufferSizeMB ,默認為30M。
2.4 重啟時緩存持久化
diskPersistent 當應用重啟時,可將緩存先持久化到硬盤,重啟後再行載入,節省大量的重新從數據庫載入。但只適合那些緩存不怎麼變化,或者有特殊機制保證重啟後應用能接收到重啟這段時間裡緩存變化信息的情況。
3. 分布式緩存
Ehcache 有傳統的RMI,1.5版的JGroups,1.6版的JMS,隨大流還是先用RMI的好些。
3.1設置自身
這裡設置在localhost的40001端口上偵聽。如果要互相同步的CahceManager不都在一台機器上的話,hostName應該是實際IP。)
<cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=localhost, port=40001,socketTimeoutMillis=2000" />
3.2 設置需要同步的對方服務器及緩存對象,
這裡設置與40002端口上的CacheManager同步User與Role對象,如果還有第三台機器,則繼續用|分割,繼續往下列。同理,在 40002端口上的cacheManager的ehcache.xml裡,就需要配置與400001,40003的互通)
也有自動發現,廣播的簡單配法,但對廣播天然恐懼,還是辛苦一點一個個靜態列表配置文件的寫了,雖然有點煩。
<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//localhost:40002/org.springside.examples.miniweb.entity.user.User|//localhost:40002/org.springside.examples.miniweb.entity.user.Role"/>
3.3 緩存對象的配置
往每一個需要緩存的對象加入子對象cacheEventListenerFactory
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true,
replicatePuts=true,
replicateUpdates=true,
replicateUpdatesViaCopy=true,
replicateRemovals=true
asynchronousReplicationIntervalMillis=<number of milliseconds">
propertySeparator="," />
replicateAsynchronously 對象同步是否異步完成,默認為true。如果比較緊急就設為false。
在一致性時間性要求不強的時候,設為異步可大大提供性能,因為它是異步立即返回的,而且可以批量提交。
replicateUpdatesViaCopy 是否將對象變更復制到所有節點,還是只是發送一個失效信息,讓對方該緩存失效,當對方需要該緩存時重新計算載入。
默認為true。鑒於對象復制的消耗挺大的,又有鎖的問題,而且對方也未必需要該對象,所以此屬性建議設為false。如果業務上真的需要設為true時,就可考慮使用Terracotta了。
replicatePuts、replicateUpdates、replicateRemovals 增刪改是否同步,默認都為true。但因為我們前面選擇了失效算法,所以replicatePuts 要設為false。
所以我們一般的設置如下:
<cache name="org.springside.examples.miniweb.entity.user.User" maxElementsInMemory="500" overflowToDisk="true"
eternal="true">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=false,replicatePuts=false,replicateUpdatesViaCopy=false" />
</cache>
3.4 Shutdown
在分布式環境或持久化硬盤時,需要調用CacheManager的shutdown操作,Hibernate會自動shutdown它自己的cacheManager,如果在hibernate之外使用,你需要增加:
<listener>
<listener-class>net.sf.ehcache.constructs.web.ShutdownListener</listener-class>
</listener>
4.JMS式並發同步
與其他同步方式相比,JMS同步支持了非Cache節點的程序對Cahce的修改。
在分布式緩存中有一種需求:應用節點更改數據庫數據後,需要通知所有緩存集群的節點,通常大家都是自行通過JMS實現的,而Ehcache的JMS Replicator提供了一種標准的方案,提供PUT,REMOVE,REMOVE_ALL的標准操作。