海水正藍(lán)

          面朝大海,春暖花開
          posts - 145, comments - 29, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          簡介: EhCache 是一個(gè)純 Java 的進(jìn)程內(nèi)緩存框架,具有快速、精干等特點(diǎn),是 Hibernate 中默認(rèn)的 CacheProvider。本文充分的介紹了 EhCache 緩存系統(tǒng)對集群環(huán)境的支持以及使用方法。

          本文的標(biāo)簽:  java, 不錯(cuò), 緩存

          發(fā)布日期: 2010 年 4 月 01 日
          級別: 初級
          訪問情況 : 13809 次瀏覽
          評論: 1 (查看 | 添加評論 - 登錄)

          平均分 5 星 共 58 個(gè)評分 平均分 (58個(gè)評分)
          為本文評分

          EhCache 緩存系統(tǒng)簡介

          EhCache 是一個(gè)純 Java 的進(jìn)程內(nèi)緩存框架,具有快速、精干等特點(diǎn),是 Hibernate 中默認(rèn)的 CacheProvider。

          下圖是 EhCache 在應(yīng)用程序中的位置:


          圖 1. EhCache 應(yīng)用架構(gòu)圖
          圖 1. EhCache 應(yīng)用架構(gòu)圖

          EhCache 的主要特性有:

          1. 快速;
          2. 簡單;
          3. 多種緩存策略;
          4. 緩存數(shù)據(jù)有兩級:內(nèi)存和磁盤,因此無需擔(dān)心容量問題;
          5. 緩存數(shù)據(jù)會在虛擬機(jī)重啟的過程中寫入磁盤;
          6. 可以通過 RMI、可插入 API 等方式進(jìn)行分布式緩存;
          7. 具有緩存和緩存管理器的偵聽接口;
          8. 支持多緩存管理器實(shí)例,以及一個(gè)實(shí)例的多個(gè)緩存區(qū)域;
          9. 提供 Hibernate 的緩存實(shí)現(xiàn);
          10. 等等 …

          由于 EhCache 是進(jìn)程中的緩存系統(tǒng),一旦將應(yīng)用部署在集群環(huán)境中,每一個(gè)節(jié)點(diǎn)維護(hù)各自的緩存數(shù)據(jù),當(dāng)某個(gè)節(jié)點(diǎn)對緩存數(shù)據(jù)進(jìn)行更新,這些更新的數(shù)據(jù)無法在其它節(jié)點(diǎn)中共享, 這不僅會降低節(jié)點(diǎn)運(yùn)行的效率,而且會導(dǎo)致數(shù)據(jù)不同步的情況發(fā)生。例如某個(gè)網(wǎng)站采用 A、B 兩個(gè)節(jié)點(diǎn)作為集群部署,當(dāng) A 節(jié)點(diǎn)的緩存更新后,而 B 節(jié)點(diǎn)緩存尚未更新就可能出現(xiàn)用戶在瀏覽頁面的時(shí)候,一會是更新后的數(shù)據(jù),一會是尚未更新的數(shù)據(jù),盡管我們也可以通過 Session Sticky 技術(shù)來將用戶鎖定在某個(gè)節(jié)點(diǎn)上,但對于一些交互性比較強(qiáng)或者是非 Web 方式的系統(tǒng)來說,Session Sticky 顯然不太適合。所以就需要用到 EhCache 的集群解決方案。

          EhCache 從 1.7 版本開始,支持五種集群方案,分別是:

          • Terracotta
          • RMI
          • JMS
          • JGroups
          • EhCache Server

          本文主要介紹其中的三種最為常用集群方式,分別是 RMI、JGroups 以及 EhCache Server 。

          回頁首

          RMI 集群模式

          RMI 是 Java 的一種遠(yuǎn)程方法調(diào)用技術(shù),是一種點(diǎn)對點(diǎn)的基于 Java 對象的通訊方式。EhCache 從 1.2 版本開始就支持 RMI 方式的緩存集群。在集群環(huán)境中 EhCache 所有緩存對象的鍵和值都必須是可序列化的,也就是必須實(shí)現(xiàn) java.io.Serializable 接口,這點(diǎn)在其它集群方式下也是需要遵守的。

          下圖是 RMI 集群模式的結(jié)構(gòu)圖:


          圖 2. RMI 集群模式結(jié)構(gòu)圖
          圖 2. RMI 集群模式結(jié)構(gòu)圖

          采用 RMI 集群模式時(shí),集群中的每個(gè)節(jié)點(diǎn)都是對等關(guān)系,并不存在主節(jié)點(diǎn)或者從節(jié)點(diǎn)的概念,因此節(jié)點(diǎn)間必須有一個(gè)機(jī)制能夠互相認(rèn)識對方,必須知道其它節(jié)點(diǎn)的信息,包括 主機(jī)地址、端口號等。EhCache 提供兩種節(jié)點(diǎn)的發(fā)現(xiàn)方式:手工配置和自動發(fā)現(xiàn)。手工配置方式要求在每個(gè)節(jié)點(diǎn)中配置其它所有節(jié)點(diǎn)的連接信息,一旦集群中的節(jié)點(diǎn)發(fā)生變化時(shí),需要對緩存進(jìn)行重 新配置。

          由于 RMI 是 Java 中內(nèi)置支持的技術(shù),因此使用 RMI 集群模式時(shí),無需引入其它的 Jar 包,EhCache 本身就帶有支持 RMI 集群的功能。使用 RMI 集群模式需要在 ehcache.xml 配置文件中定義 cacheManagerPeerProviderFactory 節(jié)點(diǎn)。假設(shè)集群中有兩個(gè)節(jié)點(diǎn),分別對應(yīng)的 RMI 綁定信息是:

          節(jié)點(diǎn) 1 192.168.0.11 4567 /oschina_cache
          節(jié)點(diǎn) 2 192.168.0.12 4567 /oschina_cache
          節(jié)點(diǎn) 3 192.168.0.13 4567 /oschina_cache

          那么對應(yīng)的手工配置信息如下:


          <cacheManagerPeerProviderFactory      
             
          class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"      
             properties
          ="hostName=localhost,     
             port=4567,     
             socketTimeoutMillis
          =2000,     
             peerDiscovery
          =manual,     
             rmiUrls
          =//192.168.0.12:4567/oschina_cache|//192.168.0.13:4567/oschina_cache" />

          其它節(jié)點(diǎn)配置類似,只需把 rmiUrls 中的兩個(gè) IP 地址換成另外兩個(gè)節(jié)點(diǎn)對應(yīng)的 IP 地址即可。

          接下來在需要進(jìn)行緩存數(shù)據(jù)復(fù)制的區(qū)域(Region)上配置如下即可:


          <cache name="sampleCache2"     
           maxElementsInMemory
          ="10"     
           eternal
          ="false"     
           timeToIdleSeconds
          ="100"     
           timeToLiveSeconds
          ="100"     
           overflowToDisk
          ="false">     
          <cacheEventListenerFactory         
           
          class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"         
           properties
          ="replicateAsynchronously=true,      
           replicatePuts=true,      
           replicateUpdates
          =true,         
           replicateUpdatesViaCopy
          =false,      
           replicateRemovals
          =true "/> 
          </cache>

          具體每個(gè)參數(shù)代表的意義請參考 EhCache 的手冊,此處不再詳細(xì)說明。

          EhCache 的 RMI 集群模式還有另外一種節(jié)點(diǎn)發(fā)現(xiàn)方式,就是通過多播( multicast )來維護(hù)集群中的所有有效節(jié)點(diǎn)。這也是最為簡單而且靈活的方式,與手工模式不同的是,每個(gè)節(jié)點(diǎn)上的配置信息都相同,大大方便了節(jié)點(diǎn)的部署,避免人為的錯(cuò)漏出現(xiàn)。

          在上述三個(gè)節(jié)點(diǎn)的例子中,配置如下:


          <cacheManagerPeerProviderFactory     
           
          class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
           properties
          ="peerDiscovery=automatic, 
           multicastGroupAddress=230.0.0.1,    
           multicastGroupPort
          =4446, timeToLive=32" />

          其中需要指定節(jié)點(diǎn)發(fā)現(xiàn)模式 peerDiscovery 值為 automatic 自動;同時(shí)組播地址可以指定 D 類 IP 地址空間,范圍從 224.0.1.0 到 238.255.255.255 中的任何一個(gè)地址。

          回頁首

          JGroups 集群模式

          EhCache 從 1.5. 版本開始增加了 JGroups 的分布式集群模式。與 RMI 方式相比較, JGroups 提供了一個(gè)非常靈活的協(xié)議棧、可靠的單播和多播消息傳輸,主要的缺點(diǎn)是配置復(fù)雜以及一些協(xié)議棧對第三方包的依賴。

          JGroups 也提供了基于 TCP 的單播 ( Unicast ) 和基于 UDP 的多播 ( Multicast ) ,對應(yīng) RMI 的手工配置和自動發(fā)現(xiàn)。使用單播方式需要指定其它節(jié)點(diǎn)的主機(jī)地址和端口,下面是兩個(gè)節(jié)點(diǎn),并使用了單播方式的配置:


          <cacheManagerPeerProviderFactory     
           
          class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory" 
           properties
          ="connect=TCP(start_port=7800):         
           TCPPING(initial_hosts=host1[7800],host2[7800]; port_range=10;timeout=3000;     
           num_initial_members
          =3;up_thread=true;down_thread=true):         
           VERIFY_SUSPECT(timeout
          =1500;down_thread=false;up_thread=false):         
           pbcast.NAKACK(down_thread
          =true;up_thread=true;gc_lag=100;     
           retransmit_timeout
          =3000):         
           pbcast.GMS(join_timeout
          =5000;join_retry_timeout=2000;shun=false;         
           print_local_addr
          =false;down_thread=true;up_thread=true)" propertySeparator="::" />

          使用多播方式配置如下:


          <cacheManagerPeerProviderFactory     
           
          class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"     
           properties
          ="connect=UDP(mcast_addr=231.12.21.132;mcast_port=45566;):PING:MERGE2:FD_SOCK:VERIFY_SUSPECT:pbcast.NAKACK:UNICAST:pbcast.STABLE:FRAG:pbcast.GMS"     propertySeparator="::" />

          從上面的配置來看,JGroups 的配置要比 RMI 復(fù)雜得多,但也提供更多的微調(diào)參數(shù),有助于提升緩存數(shù)據(jù)復(fù)制的性能。詳細(xì)的 JGroups 配置參數(shù)的具體意義可參考 JGroups 的配置手冊。

          JGroups 方式對應(yīng)緩存節(jié)點(diǎn)的配置信息如下:


          <cache name="sampleCache2"     
           maxElementsInMemory
          ="10"     
           eternal
          ="false"     
           timeToIdleSeconds
          ="100"     
           timeToLiveSeconds
          ="100"     
           overflowToDisk
          ="false">     
          <cacheEventListenerFactory
           
          class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
           properties
          ="replicateAsynchronously=true, 
           replicatePuts=true,        
           replicateUpdates
          =true
           replicateUpdatesViaCopy
          =false, replicateRemovals=true" /> 
          </cache>

          使用組播方式的注意事項(xiàng)

          使用 JGroups 需要引入 JGroups 的 Jar 包以及 EhCache 對 JGroups 的封裝包 ehcache-jgroupsreplication-xxx.jar 。

          在一些啟用了 IPv6 的電腦中,經(jīng)常啟動的時(shí)候報(bào)如下錯(cuò)誤信息:

          java.lang.RuntimeException: the type of the stack (IPv6) and the user supplied addresses (IPv4) don't match: /231.12.21.132.

          解決的辦法是增加 JVM 參數(shù):-Djava.net.preferIPv4Stack=true。如果是 Tomcat 服務(wù)器,可在 catalina.bat 或者 catalina.sh 中增加如下環(huán)境變量即可:


          SET CATALINA_OPTS=-Djava.net.preferIPv4Stack=true 

          經(jīng)過實(shí)際測試發(fā)現(xiàn),集群方式下的緩存數(shù)據(jù)都可以在 1 秒鐘之內(nèi)完成到其節(jié)點(diǎn)的復(fù)制。

          回頁首

          EhCache Server

          與前面介紹的兩種集群方案不同的是, EhCache Server 是一個(gè)獨(dú)立的緩存服務(wù)器,其內(nèi)部使用 EhCache 做為緩存系統(tǒng),可利用前面提到的兩種方式進(jìn)行內(nèi)部集群。對外提供編程語言無關(guān)的基于 HTTP 的 RESTful 或者是 SOAP 的數(shù)據(jù)緩存操作接口。

          下面是 EhCache Server 提供的對緩存數(shù)據(jù)進(jìn)行操作的方法:

          OPTIONS /{cache}}

          獲取某個(gè)緩存的可用操作的信息。

          HEAD /{cache}/{element}

          獲取緩存中某個(gè)元素的 HTTP 頭信息,例如:


          curl --head  http://localhost:8080/ehcache/rest/sampleCache2/2 

          EhCache Server 返回的信息如下:


          HTTP/1.1 200 OK  X-Powered-By: Servlet/2.5  
          Server: GlassFish
          /v3  Last-Modified: Sun, 27 Jul 2008 08:08:49 GMT  
          ETag: 
          "1217146129490" Content-Type: text/plain; charset=iso-8859-1  
          Content
          -Length: 157  Date: Sun, 27 Jul 2008 08:17:09 GMT 

          GET /{cache}/{element}

          讀取緩存中某個(gè)數(shù)據(jù)的值。

          PUT /{cache}/{element}

          寫緩存。

          由于這些操作都是基于 HTTP 協(xié)議的,因此你可以在任何一種編程語言中使用它,例如 Perl、PHP 和 Ruby 等等。

          下圖是 EhCache Server 在應(yīng)用中的架構(gòu):


          圖 3. EhCache Server 應(yīng)用架構(gòu)圖
          圖 3. EhCache Server 應(yīng)用架構(gòu)圖

          EhCache Server 同時(shí)也提供強(qiáng)大的安全機(jī)制、監(jiān)控功能。在數(shù)據(jù)存儲方面,最大的 Ehcache 單實(shí)例在內(nèi)存中可以緩存 20GB。最大的磁盤可以緩存 100GB。通過將節(jié)點(diǎn)整合在一起,這樣緩存數(shù)據(jù)就可以跨越節(jié)點(diǎn),以此獲得更大的容量。將緩存 20GB 的 50 個(gè)節(jié)點(diǎn)整合在一起就是 1TB 了。

          回頁首

          總結(jié)

          以上我們介紹了三種 EhCache 的集群方案,除了第三種跨編程語言的方案外,EhCache 的集群對應(yīng)用程序的代碼編寫都是透明的,程序人員無需考慮緩存數(shù)據(jù)是如何復(fù)制到其它節(jié)點(diǎn)上。既保持了代碼的輕量級,同時(shí)又支持龐大的數(shù)據(jù)集群。 EhCache 可謂是深入人心。

          2009 年年中,Terracotta 宣布收購 EhCache 產(chǎn)品。Terracotta 公司的產(chǎn)品 Terracotta 是一個(gè) JVM 級的開源群集框架,提供 HTTP Session 復(fù)制、分布式緩存、POJO 群集、跨越集群的 JVM 來實(shí)現(xiàn)分布式應(yīng)用程序協(xié)調(diào)。最近 EhCache 主要的改進(jìn)都集中在跟 Terracotta 框架的集成上,這是一個(gè)真正意義上的企業(yè)級緩存解決方案。


          參考資料

          學(xué)習(xí)

          獲得產(chǎn)品和技術(shù)

          討論

          關(guān)于作者

          劉柄成,開源中國社區(qū)(http://www.oschina.net)站長,DLOG4J 作者,十年的 Java 開發(fā)經(jīng)驗(yàn),熱衷于開源軟件的開發(fā)和應(yīng)用。


          http://www.ibm.com/developerworks/cn/java/j-lo-ehcache/

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 张家口市| 马尔康县| 莆田市| 诸暨市| 方城县| 洞头县| 兴化市| 绥芬河市| 新田县| 西安市| 洮南市| 鄯善县| 东莞市| 辛集市| 临邑县| 泸水县| 大丰市| 惠安县| 通州市| 鸡泽县| 晴隆县| 泸水县| 剑川县| 长岛县| 桦甸市| 铁岭县| 花莲县| 梓潼县| 郎溪县| 沭阳县| 施秉县| 嘉善县| 边坝县| 西乌珠穆沁旗| 镇赉县| 桃江县| 涞水县| 杭锦旗| 贞丰县| 社会| 通榆县|