1. 程式人生 > >ehcache、memcache、redis三種快取的比較

ehcache、memcache、redis三種快取的比較

Ehcache
EhCache 是一個純Java的程序內快取框架,具有快速、精幹等特點,是Hibernate中預設的CacheProvider。Ehcache是一種廣泛使用的開源Java分散式快取。
優點:快速
簡單
快取資料有兩級:記憶體和磁碟,因此無需擔心容量問題
快取資料會在虛擬機器重啟的過程中寫入磁碟
可以通過RMI、可插入API等方式進行分散式快取
具有快取和快取管理器的偵聽介面
支援多快取管理器例項,以及一個例項的多個快取區域
提供Hibernate的快取實現
多種快取策略,Ehcache提供了對大資料的記憶體和硬碟的儲存,最近版本允許多例項、儲存物件高靈活性、提供LRU、LFU、FIFO淘汰演算法,基礎屬性支援熱配置、支援的外掛多

缺點:
使用磁碟Cache的時候非常佔用磁碟空間;
不能保證資料的安全

引數配置:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 系統快取 -->
<cache name="sysCache" maxElementsInMemory="1000" eternal="true" overflowToDisk="true"/>

<!--   
eternal:快取中物件是否為永久的,如果是,超時設定將被忽略,物件從不過期。  
maxElementsInMemory:快取中允許建立的最大物件數  
overflowToDisk:記憶體不足時,是否啟用磁碟快取。  
timeToIdleSeconds:快取資料的鈍化時間,也就是在一個元素消亡之前,  
        兩次訪問時間的最大時間間隔值,這隻能在元素不是永久駐留時有效,  
 如果該值是 0 就意味著元素可以停頓無窮長的時間。  
timeToLiveSeconds:快取資料的生存時間,也就是一個元素從構建到消亡的最大時間間隔值,  
       這隻能在元素不是永久駐留時有效,如果該值是0就意味著元素可以停頓無窮長的時間。  
memoryStoreEvictionPolicy:快取滿了之後的淘汰演算法。  
1 FIFO,先進先出  
2 LFU,最少被使用,快取的元素有一個hit屬性,hit值最小的將會被清出快取。  
3 LRU,最近最少使用的,快取的元素有一個時間戳,當快取容量滿了,而又需要騰出地方來快取新的元素的時候,那麼現有快取元素中時間戳離當前時間最遠的元素將被清出快取。  
-->  
<cache name="shiro-activeSessionCache"  
       maxElementsInMemory="1000"  
       overflowToDisk="true"  
       timeToLiveSeconds="0"  
       timeToIdleSeconds="0"  
       diskPersistent="true"  
       diskExpiryThreadIntervalSeconds="600"/>  

EhCache的分散式快取有傳統的RMI,1.5版的JGroups,1.6版的JMS。

<?xml version="1.0" encoding="UTF-8"?>
<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
    properties="peerDiscovery=automatic,multicastGroupAddress=230.0.0.1, multicastGroupPort=4446" />
<cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" />

<!-- 預設快取配置. -->
<defaultCache maxEntriesLocalHeap="100" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600"
    overflowToDisk="true" maxEntriesLocalDisk="100000" >
    <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
        properties="replicatePuts=false,replicateUpdatesViaCopy=false"/>
</defaultCache>

<!-- 系統快取 -->
<cache name="sysCache" maxEntriesLocalHeap="100" eternal="true" overflowToDisk="true">
    <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
</cache>

<!-- 系統活動會話快取 -->
<cache name="shiro-activeSessionCache" maxEntriesLocalHeap="10000" overflowToDisk="true"
        eternal="true" timeToLiveSeconds="0" timeToIdleSeconds="0"
        diskPersistent="true" diskExpiryThreadIntervalSeconds="600">
    <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
        properties="replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true,
            replicateUpdatesViaCopy=false, replicateRemovals=true "/>
</cache>

當快取改變時,ehcache會向230.0.0.1埠4446發RMI UDP組播包。

分散式快取不建議使用ehcache, 建議使用redis或Memcache

2.memcache
memcache 是一種高效能、分散式物件快取系統,最初設計於緩解動態網站資料庫載入資料的延遲性,你可以把它想象成一個大的記憶體HashTable,就是一個key-value鍵值快取。

memcache C語言所編寫,依賴於最近版本的GCC和libevent。多執行緒支援
優點:
一.部分容災
假設只用一臺memcache,如果這臺memcache伺服器掛掉了,那麼請求將不斷的衝擊資料庫,這樣有可能搞死資料庫,從而引發”雪崩“。如果使用多臺memcache伺服器,由於memcache使用一致性雜湊演算法,萬一其中一臺掛掉了,部分請求還是可以在memcache中命中,為修復系統贏得一些時間。
二.容量問題
一臺memcache伺服器的容量畢竟有限,可以使用多臺memcache伺服器,增加快取容量。
三.均衡請求
使用多臺memcache伺服器,可以均衡請求,避免所有請求都衝進一臺memcache伺服器,導致伺服器掛掉。
四.利用memcache分散式特性
使用一臺memcache伺服器,並沒有利用memcache的資料分散式特性。

缺點:
1.不能持久化儲存
2.儲存資料有限制:1M 【大於1M,認為就行分割】(記憶體碎片)
3.mm儲存資料只能key-value
4.叢集資料沒有複製和同步機制 【崩潰不會影響程式,會從資料庫中取資料】
5.記憶體回收不能及時 LRU(演算法):未使用記憶體》過期記憶體》最近最少使用記憶體 這是惰性刪除

3、redis
單執行緒、讀寫效能優異、支援資料持久化,支援AOF和RDB兩種持久化方式、支援主從複製,主機會自動將資料同步到從機,可以進行讀寫分離;資料結構豐富:除了支援string型別的value外還支援string、hash、set、sortedset、list等資料結構。

缺點:
1 Redis不具備自動容錯和恢復功能,主機從機的宕機都會導致前端部分讀寫請求失敗,需要等待機器重啟或者手動切換前端的IP才能恢復。
2 主機宕機,宕機前有部分資料未能及時同步到從機,切換IP後還會引入資料不一致的問題,降低了系統的可用性。
3 Redis的主從複製採用全量複製,複製過程中主機會fork出一個子程序對記憶體做一份快照,並將子程序的記憶體快照儲存為檔案傳送給從機,這一過程需要確保主機有足夠多的空餘記憶體。若快照檔案較大,對叢集的服務能力會產生較大的影響,而且複製過程是在從機新加入叢集或者從機和主機網路斷開重連時都會進行,也就是網路波動都會造成主機和從機間的一次全量的資料複製,這對實際的系統運營造成了不小的麻煩。
4 Redis較難支援線上擴容,在叢集容量達到上限時線上擴容會變得很複雜。為避免這一問題,運維人員在系統上線時必須確保有足夠的空間,這對資源造成了很大的浪費。

ehcache直接在jvm虛擬機器中快取,速度快,效率高;但是快取共享麻煩,叢集分散式應用不方便。
redis是通過socket訪問到快取服務,效率比ecache低,比資料庫要快很多,處理叢集和分散式快取方便,有成熟的方案。
如果是單個應用或者對快取訪問要求很高的應用,用ehcache。
如果是大型系統,存在快取共享、分散式部署、快取內容很大的,建議用redis。