TreeCache是一種結(jié)構(gòu)化的、基于復(fù)制的事務(wù)緩存。TreeCache是JBoss應(yīng)用服務(wù)器中集群服務(wù)—包括JNDI集群、HTTP和EJB的Sesssion集群、JMS集群—的基礎(chǔ)框架。其可以單獨(dú)

使用, 可以集成到JBossAS應(yīng)用,也可以集成到其他的應(yīng)用服務(wù)器上。TreeCache是一種樹狀結(jié)構(gòu),每個(gè)節(jié)點(diǎn)擁有一個(gè)名字和多個(gè)或者沒(méi)有子節(jié)點(diǎn),除跟節(jié) 點(diǎn)沒(méi)有子節(jié)點(diǎn)其他節(jié)點(diǎn)有且只有一個(gè)父母節(jié)點(diǎn),可以通過(guò)路徑名來(lái)訪問(wèn)子節(jié)點(diǎn)(FQN:Full   Qualified   Name),在一個(gè)TreeCache中可以存在多棵樹,,即可以有多個(gè)根節(jié)點(diǎn)。當(dāng)應(yīng)用于分布式環(huán)境時(shí),由于TreeCache是基于復(fù)制的,每個(gè)子節(jié)點(diǎn)的值必須是可序列化的。  
            在下面中,將通過(guò)例子來(lái)了解TreeCache的功能及其配置,使用JBossCache1.4和JDK5.0。首先是一個(gè)最基本使用TreeCache 的程序例子并配置一個(gè)TreeCache的配置骨架(各種常用的配置可參見(jiàn)jboss-cache-dist-1.4.0.CR1版本的etc目錄,如下 各種配置參考也可見(jiàn)該目錄下的范例配置,以下不再?gòu)?qiáng)調(diào)),見(jiàn)下:  
  [code]  
  TreeCache   tree   =   new   TreeCache();  
  tree.setClusterProperties("treecache.xml");    
  tree.createService();    
  tree.startService();    
  tree.put("/a/b/c",   "name",   "Ben");  
  tree.put("/a/b/c/d",   "uid",   new   Integer(322649));  
  Integer   tmp   =   (Integer)   tree.get("/a/b/c/d",   "uid");  
  tree.remove("/a/b");  
  tree.stopService();  
  tree.destroyService();    
  [/code]  
  [code]  
  treecache.xml:  
  <server>  
          <mbean   code="org.jboss.cache.TreeCache"  
                  name="jboss.cache:service=TreeCache">  
                  <depends>jboss:service=Naming</depends>  
                  <depends>jboss:service=TransactionManager</depends>  
                  <attribute   name="ClusterName">TreeCache-Cluster</attribute>  
                  <attribute   name="ClusterConfig">  
                          <config>  
                                  <UDP   mcast_addr="228.1.2.3"   mcast_port="48866"  
                                          ip_ttl="64"   ip_mcast="true"    
                                          mcast_send_buf_size="150000"   mcast_recv_buf_size="80000"  
                                          ucast_send_buf_size="150000"   ucast_recv_buf_size="80000"  
                                          loopback="false"/>  
                                  <PING   timeout="2000"   num_initial_members="3"  
                                          up_thread="false"   down_thread="false"/>  
                                  <MERGE2   min_interval="10000"   max_interval="20000"/>  
                                  <FD_SOCK/>  
                                  <VERIFY_SUSPECT   timeout="1500"  
                                          up_thread="false"   down_thread="false"/>  
                                  <pbcast.NAKACK   gc_lag="50"   retransmit_timeout="600,1200,2400,4800"  
                                          max_xmit_size="8192"   up_thread="false"   down_thread="false"/>  
                                  <UNICAST   timeout="600,1200,2400"   window_size="100"   min_threshold="10"  
                                          down_thread="false"/>  
                                  <pbcast.STABLE   desired_avg_gossip="20000"  
                                          up_thread="false"   down_thread="false"/>  
                                  <FRAG   frag_size="8192"  
                                          down_thread="false"   up_thread="false"/>  
                                  <pbcast.GMS   join_timeout="5000"   join_retry_timeout="2000"  
                                          shun="true"   print_local_addr="true"/>  
                                  <pbcast.STATE_TRANSFER   up_thread="true"   down_thread="true"/>  
                          </config>  
                  </attribute>  
          </mbean>  
  </server>  
  [/code]  
            其中ClusterConfig配置在前面JavaGroups的介紹詳細(xì)介紹,其它配置比較簡(jiǎn)單,需要進(jìn)一步了解請(qǐng)參見(jiàn)TreeCache文檔。



一、Cache分類  
            TreeCache按功能分為三類:本地(Local)Cache、復(fù)制(Replication)Cache和失效(Invalidation) Cache。本地Cache只應(yīng)用于本地環(huán)境,后兩個(gè)Cache可應(yīng)用于分布式環(huán)境,其中,在分布式環(huán)境中,復(fù)制Cache當(dāng)一個(gè)Cache實(shí)例的一個(gè)節(jié) 點(diǎn)值發(fā)生變化時(shí)會(huì)將變化復(fù)制到其它實(shí)例中,而失效Cache是當(dāng)一個(gè)Cache實(shí)例的一個(gè)節(jié)點(diǎn)值發(fā)生變化時(shí)會(huì)將其它實(shí)例的相應(yīng)節(jié)點(diǎn)的值設(shè)為空,讓其重新去 獲得該值,可通過(guò)這種方式緩存大對(duì)象以減少在實(shí)例中復(fù)制對(duì)象的代價(jià)。分布式Cache(復(fù)制和失效Cache)又分為兩種,同步(REPL_ASYNC) 和異步(REPL_SYNC),同步Cache是在一個(gè)Cache實(shí)例做修改時(shí),等待變化應(yīng)用到其它實(shí)例后才返回,而異步Cache是在一個(gè)Cache實(shí) 例做修改時(shí),即刻返回。其配置見(jiàn)下:  
  [code]  
  <!--  
        Valid   modes   are   LOCAL  
                                        REPL_ASYNC  
                                        REPL_SYNC  
                                        INVALIDATION_ASYNC  
                                        INVALIDATION_SYNC  
  -->  
  <attribute   name="CacheMode">REPL_SYNC</attribute>  
  [/code]  
            二、事務(wù)和并行(Transaction   And   Concurrent)  
              TreeCache是一種事務(wù)Cache,與JDBC一樣,其包括兩方面內(nèi)容:鎖和隔離級(jí)別。鎖分為悲觀鎖和樂(lè)觀鎖,當(dāng)使用悲觀鎖時(shí),分為五個(gè)隔離級(jí)別, 分別是SERIALIZABLE、REPEATABLE_READ   (default)、READ_COMMITTED、READ_UNCOMMITTED和NONE,隔離級(jí)別逐步減弱。樂(lè)觀鎖也叫版本鎖,其對(duì)

數(shù)據(jù)進(jìn) 行操作時(shí),將其復(fù)制到臨時(shí)區(qū),操作之后將版本與原有數(shù)據(jù)比較,如果一致則將遞增版本并寫回,如果不一致則回滾,由于樂(lè)觀鎖僅在復(fù)制出數(shù)據(jù)和提交數(shù)據(jù)時(shí)對(duì)數(shù) 據(jù)加鎖,所以并行度更高,但如果寫操作比較頻繁地話則容易出現(xiàn)沖突導(dǎo)致回滾。TreeCache默認(rèn)使用悲觀鎖。使用TreeCache時(shí),需要使用容器 提供的事務(wù)管理器,一般使JBossTransactionManagerLookup和 GenericTransactionManagerLookup,前者應(yīng)用于JBOSS服務(wù)器,后者應(yīng)用于其他服務(wù)器,也可使用DummyTransactionManagerLookup用于測(cè)試。如上介紹的配置如下:  
  [code]  
                <attribute   name="NodeLockingScheme">OPTIMISTIC</attribute>  
                <attribute   name="IsolationLevel">REPEATABLE_READ</attribute>  
              <attribute   name="TransactionManagerLookupClass">org.jboss.cache.DummyTransactionManagerLookup</attribute>  
  [/code]  
            三、逐出策略(Eviction   Policy)  
              由于內(nèi)存數(shù)量的 局限,不可能將所有的Cache數(shù)據(jù)存放在內(nèi)存中,但使用內(nèi)存達(dá)到一定極限時(shí),會(huì)將部分?jǐn)?shù)據(jù)清除出內(nèi)存,保存到其它持久媒質(zhì)中,定義的什么時(shí)候清除、如何 清除的策略就是逐出策略。自定義一個(gè)逐出策略需要實(shí)現(xiàn)org.jboss.cache.eviction.EvictionPolicy、 org.jboss.cache.eviction.EvictionAlgorithm、  
    org.jboss.cache.eviction.EvictionQueue   和org.jboss.cache.eviction.EvictionConfiguration四個(gè)接口,系統(tǒng)提 供了LRU(Least   recently   used,最近最少使用)、LFU(Least   Frequently   Used最不經(jīng)常使用)、FIFO(First   In   First   Out先進(jìn)先出)、MRU(Most   Recently   Used最近最經(jīng)常使用)四種實(shí)現(xiàn),詳細(xì)參見(jiàn)org.jboss.cache.eviction包的源代碼。配置如下:  
  [code]  
  <attribute   name="EvictionPolicyConfig">  
        <config>  
              <attribute   name="wakeUpIntervalSeconds">5</attribute>  
              <region   name="/_default_">  
                  <attribute   name="maxNodes">5000</attribute>  
                  <attribute   name="timeToLiveSeconds">1000</attribute>  
              </region>  
              <region   name="/org/jboss/data"  
  policyClass="org.jboss.cache.eviction.FIFOPolicy">  
                  <attribute   name="maxNodes">5000</attribute>  
              </region>  
              <region   name="/test/"   policyClass="org.jboss.cache.eviction.MRUPolicy">  
                  <attribute   name="maxNodes">10000</attribute>  
              </region>  
              <region   name="/maxAgeTest/">  
                  <attribute   name="maxNodes">10000</attribute>  
                  <attribute   name="timeToLiveSeconds">8</attribute>  
                  <attribute   name="maxAgeSeconds">10</attribute>  
              </region>  
        </config>  
  </attribute>  
  [/code]  
            也可以多對(duì)所有的區(qū)域定義同樣的逐出策略  
  [code]  
  <attribute   name="EvictionPolicyClass">org.jboss.cache.eviction.LFUPolicy</attribute>  
  [/code]  
            四、Cache加載  
          由于逐出策略的存在,那么當(dāng)我們重新需要獲得一個(gè)原來(lái)在緩存中但確由內(nèi)存原因被逐出的數(shù)據(jù)時(shí),就需要定義一種加載策略,使地可以重新找回?cái)?shù)據(jù),同時(shí),Cache加載也肩負(fù)在將數(shù)據(jù)逐出時(shí)將數(shù)據(jù)保存到持久媒質(zhì)的責(zé)任。  
          根據(jù)將數(shù)據(jù)保存媒質(zhì)的不同,Cache加載包括FileCacheLoader、JDBCCacheLoader等等,可以同時(shí)使用多種加載器來(lái)靈活定制加載策略。例見(jiàn)下:  
  [code]  
  <attribute   name="CacheLoaderConfiguration">  
          <config>  
                  <passivation>false</passivation>  
                  <preload>/</preload>  
                  <shared>true</shared>  
                  <cacheloader>  
                          <class>org.jboss.cache.loader.ClusteredCacheLoader</class>  
                          <properties>  
                                    timeout=1000  
                          </properties>  
                          <async>true</async>  
                          <fetchPersistentState>false</fetchPersistentState>  
                          ignoreModifications>false</ignoreModifications>  
                          <purgeOnStartup>false</purgeOnStartup>  
                  </cacheloader>  
                  <cacheloader>  
                          <class>org.jboss.cache.loader.JDBCCacheLoader</class>  
                          <properties>  
                                                  cache.jdbc.table.name=jbosscache  
                                                  cache.jdbc.table.create=true  
                                                  cache.jdbc.table.drop=true  
                                                  cache.jdbc.table.primarykey=jbosscache_pk  
                                                  cache.jdbc.fqn.column=fqn  
                                                  cache.jdbc.fqn.type=varchar(255)  
                                                  cache.jdbc.node.column=node  
                                                  cache.jdbc.node.type=longblob  
                                                  cache.jdbc.parent.column=parent  
                                                  cache.jdbc.driver=com.mysql.jdbc.Driver  
                                                  cache.jdbc.url=jdbc:mysql://localhost:3306/jbossdb  
                                                  cache.jdbc.user=root  
                                                  cache.jdbc.password=  
                            </properties>  
                            <async>true</async>  
                            <fetchPersistentState>false</fetchPersistentState>  
                            <purgeOnStartup>false</purgeOnStartup>  
                    </cacheloader>  
          </config>  
  </attribute>  
  [/code]  
          我們將通過(guò)定制如上的配置信息以更有效地使用JBossCache。詳細(xì)情況可參考JBoss   TreeCache參考文檔和范例。