<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    paulwong

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

    EhCache 是一個(gè)純Java的進(jìn)程內(nèi)緩存框架,具有快速、精干等特點(diǎn),是Hibernate中默認(rèn)的CacheProvider。
    下圖是 EhCache 在應(yīng)用程序中的位置:
    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 版本開始,支持五種集群方案,分別是:
    1. Terracotta
    2. RMI
    3. JMS
    4. JGroups
    5. 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)圖:
    采用 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)的手工配置信息如下:
    節(jié)點(diǎn)1配置:

    <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)方式,就是通過多播( multi_cast )來維護(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, multi_castGroupAddress=230.0.0.1,
    multi_castGroupPort=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 的單播 ( Uni_cast ) 和基于 UDP 的多播 ( Multi_cast ) ,對應(yīng) RMI 的手工配置和自動發(fā)現(xiàn)。使用單播方式需要指定其他節(jié)點(diǎn)的主機(jī)地址和端口,下面是一個(gè)兩個(gè)節(jié)點(diǎn),使用了單播方式的配置,TCP方式必須用文件的方式才行:

    <cacheManagerPeerProviderFactory
            
    class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"
            properties
    ="file=jgroups_tcp.xml, syncMode=GET_ALL, syncTimeout=10000" />

    jgroups_tcp.xml
    <!--
        TCP based stack, with flow control and message bundling. This is usually used when IP
        multicasting cannot be used in a network, e.g. because it is disabled (routers discard multicast).
        Note that TCP.bind_addr and TCPPING.initial_hosts should be set, possibly via system properties, e.g.
        -Djgroups.bind_addr=192.168.5.2 and -Djgroups.tcpping.initial_hosts=192.168.5.2[7800]
        author: Bela Ban
        version: $Id: tcp.xml,v 1.40 2009/12/18 09:28:30 belaban Exp $
    -->
    <config xmlns="urn:org:jgroups"
            xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation
    ="urn:org:jgroups http://www.jgroups.org/schema/JGroups-2.8.xsd">
        
    <TCP bind_port="7800"
             loopback
    ="true"
             recv_buf_size
    ="${tcp.recv_buf_size:20M}"
             send_buf_size
    ="${tcp.send_buf_size:640K}"
             discard_incompatible_packets
    ="true"
             max_bundle_size
    ="64K"
             max_bundle_timeout
    ="30"
             enable_bundling
    ="true"
             use_send_queues
    ="true"
             sock_conn_timeout
    ="300"
             timer.num_threads
    ="4"
             
             thread_pool.enabled
    ="true"
             thread_pool.min_threads
    ="1"
             thread_pool.max_threads
    ="10"
             thread_pool.keep_alive_time
    ="5000"
             thread_pool.queue_enabled
    ="false"
             thread_pool.queue_max_size
    ="100"
             thread_pool.rejection_policy
    ="discard"

             oob_thread_pool.enabled
    ="true"
             oob_thread_pool.min_threads
    ="1"
             oob_thread_pool.max_threads
    ="8"
             oob_thread_pool.keep_alive_time
    ="5000"
             oob_thread_pool.queue_enabled
    ="false"
             oob_thread_pool.queue_max_size
    ="100"
             oob_thread_pool.rejection_policy
    ="discard"/>
                             
        
    <TCPPING timeout="3000"
                 initial_hosts
    ="${jgroups.tcpping.initial_hosts:192.168.1.200[7800],192.168.1.200[7801]}"
                 port_range
    ="1"
                 num_initial_members
    ="3"/>
        
    <MERGE2  min_interval="10000"
                 max_interval
    ="30000"/>
        
    <FD_SOCK/>
        
    <FD timeout="3000" max_tries="3" />
        
    <VERIFY_SUSPECT timeout="1500"  />
        
    <BARRIER />
        
    <pbcast.NAKACK
                       use_mcast_xmit
    ="false" gc_lag="0"
                       retransmit_timeout
    ="300,600,1200,2400,4800"
                       discard_delivered_msgs
    ="true"/>
        
    <UNICAST timeout="300,600,1200" />
        
    <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
                       max_bytes
    ="400K"/>
        
    <pbcast.GMS print_local_addr="true" join_timeout="3000"

                    view_bundling
    ="true"/>
        
    <FC max_credits="2M"
            min_threshold
    ="0.10"/>
        
    <FRAG2 frag_size="60K"  />
        
    <pbcast.STREAMING_STATE_TRANSFER/>
        
    <!-- <pbcast.STATE_TRANSFER/> -->  
    </config>

    使用多播方式配置如下:

    <!--
      Default stack using IP multicasting. It is similar to the "udp"
      stack in stacks.xml, but doesn't use streaming state transfer and flushing
      author: Bela Ban
      version: $Id: udp.xml,v 1.40 2010/02/08 07:11:15 belaban Exp $
    -->

    <config xmlns="urn:org:jgroups"
            xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation
    ="urn:org:jgroups http://www.jgroups.org/schema/JGroups-2.8.xsd">
        
    <UDP
             
    mcast_port="${jgroups.udp.mcast_port:45588}"
             tos
    ="8"
             ucast_recv_buf_size
    ="20M"
             ucast_send_buf_size
    ="640K"
             mcast_recv_buf_size
    ="25M"
             mcast_send_buf_size
    ="640K"
             loopback
    ="true"
             discard_incompatible_packets
    ="true"
             max_bundle_size
    ="64K"
             max_bundle_timeout
    ="30"
             ip_ttl
    ="${jgroups.udp.ip_ttl:2}"
             enable_bundling
    ="true"
             enable_diagnostics
    ="true"
             thread_naming_pattern
    ="cl"
             timer.num_threads
    ="4"

             thread_pool.enabled
    ="true"
             thread_pool.min_threads
    ="2"
             thread_pool.max_threads
    ="8"
             thread_pool.keep_alive_time
    ="5000"
             thread_pool.queue_enabled
    ="true"
             thread_pool.queue_max_size
    ="10000"
             thread_pool.rejection_policy
    ="discard"

             oob_thread_pool.enabled
    ="true"
             oob_thread_pool.min_threads
    ="1"
             oob_thread_pool.max_threads
    ="8"
             oob_thread_pool.keep_alive_time
    ="5000"
             oob_thread_pool.queue_enabled
    ="false"
             oob_thread_pool.queue_max_size
    ="100"
             oob_thread_pool.rejection_policy
    ="Run"/>

        
    <PING timeout="2000"
                num_initial_members
    ="3"/>
        
    <MERGE2 max_interval="30000"
                min_interval
    ="10000"/>
        
    <FD_SOCK/>
        
    <FD_ALL/>
        
    <VERIFY_SUSPECT timeout="1500"  />
        
    <BARRIER />
        
    <pbcast.NAKACK use_stats_for_retransmission="false"
                       exponential_backoff
    ="0"
                       use_mcast_xmit
    ="true" gc_lag="0"
                       retransmit_timeout
    ="300,600,1200"
                       discard_delivered_msgs
    ="true"/>
        
    <UNICAST timeout="300,600,1200"/>
        
    <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
                       max_bytes
    ="1M"/>
        
    <pbcast.GMS print_local_addr="true" join_timeout="3000"

                    view_bundling
    ="true"/>
        
    <FC max_credits="500K"
                        min_threshold
    ="0.20"/>
        
    <FRAG2 frag_size="60K"  />
        
    <!--pbcast.STREAMING_STATE_TRANSFER /-->
        
    <pbcast.STATE_TRANSFER  />
        
    <!-- pbcast.FLUSH  /-->
    </config>

    從上面的配置來看,JGroups 的配置要比 RMI 復(fù)雜得多,但也提供更多的微調(diào)參數(shù),有助于提升緩存數(shù)據(jù)復(fù)制的性能。詳細(xì)的 JGroups 配置參數(shù)的具體意義可參考 JGroups 的配置手冊。
    JGroups 方式對應(yīng)緩存節(jié)點(diǎn)的配置信息如下:

     
    <cache name="mycache"
    maxElementsInMemory
    ="10000"
    eternal
    ="false"
    timeToIdleSeconds
    ="600"
    overflowToDisk
    ="false">
    <cacheEventListenerFactory
    class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
    properties
    ="replicateAsynchronously=true, replicatePuts=true,
    replicateUpdates=true, replicateUpdatesViaCopy=false, replicateRemovals=true"
    />
    <bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.jgroups.JGroupsBootstrapCacheLoaderFactory" />
    </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ù)緩存操作接口。
    項(xiàng)目是 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):
    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è)級緩存解決方案。

    posted on 2012-01-24 20:32 paulwong 閱讀(1440) 評論(0)  編輯  收藏 所屬分類: 緩存

    主站蜘蛛池模板: 国产亚洲蜜芽精品久久| 91福利免费网站在线观看| 最新亚洲成av人免费看| 成视频年人黄网站免费视频| 亚洲阿v天堂在线2017免费| 久久久久久亚洲精品成人| 国产精品无码亚洲精品2021 | 成全高清视频免费观看| 国产L精品国产亚洲区久久 | 成人特级毛片69免费观看| 91福利视频免费| 亚洲人成无码网站久久99热国产| 亚洲人成777在线播放| 成人无码精品1区2区3区免费看 | 久久久亚洲精品蜜桃臀| 激情综合亚洲色婷婷五月| a级毛片在线免费| 国产老女人精品免费视频| 亚洲一二成人精品区| 中文字幕无码播放免费| 一区二区无码免费视频网站| 亚洲AV一宅男色影视| 男女猛烈无遮掩视频免费软件| 成人免费观看一区二区| 亚洲精品国偷自产在线| 国产亚洲精品美女久久久久 | 最近中文字幕大全中文字幕免费| 亚洲综合精品网站| 亚洲日韩久久综合中文字幕| 99国产精品视频免费观看| 亚洲综合另类小说色区色噜噜| 亚洲国产乱码最新视频| 日韩免费人妻AV无码专区蜜桃 | 亚洲最大免费视频网| 免费在线观影网站| 免费在线视频一区| 亚洲熟妇久久精品| 美女被免费网站91色| 免费一级一片一毛片| 亚洲情A成黄在线观看动漫软件 | 亚洲国产精品成人AV无码久久综合影院|