Terracotta 集羣

如何實現集羣的。java

測試代碼編寫node

咱們首先寫一個demo,該demo在沒有terracotta的環境下執行一次,看看結果
咱們首先先寫一個簡單的多線程代碼(咱們這個例子制定共享TerracottaDemo類的demo對象,它包含的count和yale對象也就隨之被整個集羣共享了):linux

 

package yale.terracotta.demo;  
  
public class TerracottaDemo implements Runnable {  
    private static TerracottaDemo demo = new TerracottaDemo();  
    private Object yale = new Object();  
    private int count = 0;  
  
    @Override  
    public void run() {  
        while (true) {  
            synchronized (yale) {  
                count++;  
                System.out.println(Thread.currentThread().getName() + " count:"  
                        + count);  
            }  
            try {  
                Thread.sleep((int) (1000 + Math.random()));  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
    }  
  
    public static void main(String[] args) {  
        new Thread(demo).start();  
        new Thread(demo).start();  
    }  
}  

 

  該class文件存放在:web

  

 

 執行,開啓不一樣的進程進行執行,看看結果:算法

 

 

上述執行環境是在win下,經過以上的執行狀況咱們能夠看出,正常狀況下各個進程調用各自JVM中的對象,並無任何的共享express

 

下載、安裝
下載Terracotta,下載前須要註冊賬號才能進行下載:
http://terracotta.org/apache

 

從上面的信息中,咱們能夠看到,註冊成功後進行郵件驗證,驗證成功後點擊網站」open source」後,能夠對其產品Ehcache、Quartz、BigMemory下載,咱們下載terracotta (目前最高版本: terracotta-3.6.2.tar.gz、terracotta-ee-3.6.2-installer.jar)後:
安裝方法一:解壓相應的tar文件到相應的目錄便可(Linux版本)便可
安裝方法二:經過java –jar terracotta-ee-3.6.2-installer.jar
其實解壓後的文件夾中,包含了相應的ehcache、quartz的相關產品緩存

Terracotta Server配置方式
一、 單機,無持久化:服務器把集羣要管理的數據保存在內存中,當數據量大於服務器可用內存的時候,會發生內存溢出錯誤。這種模式通常只在開發中使用;
二、 單機,持久化:服務器把集羣要管理的數據保存在硬盤中,利用服務器上的內存做爲緩存,以提升經常使用數據的訪問速度。當數據量大於服務器可用內存的時候,服務器會把不經常使用數據從內存中移除,這樣就不會發生內存溢出問題。當服務器宕機,而後被重新啓動之後,硬盤中的數據被重新激活,這樣集羣中共享的數據不會丟失。這種配置提供了必定的災難恢復(Fail over)的能力,可是仍是沒法作到高可用性(HA);
三、 雙機或者多機鏡像(mirroring):通常由兩臺或者多臺物理服務器互爲鏡像。其中一臺做爲主服務器支持集羣運行。其它備用服務器只是對數據作鏡像,而且監視主服務器的狀態。當主服務器發生故障宕機的時候,其中一臺備用服務器自動升級爲主服務器,接管整個集羣的支撐工做。這樣一來整個集羣還繼續正常運行,不會受任何影響。這種配置能夠實現高可用性。通常對於這種配置模式,咱們還把服務器數據配置爲持久化模式,可是若是內存數量不是問題,用戶也能夠選擇非持久化;
四、 服務器陣列分片模式(Server Array Striping):這是Terracotta FX系列產品獨有的高端企業級特性,它主要用於提升集羣性能。當集羣中數據量和數據訪問頻率過高的時候,能夠配置多臺服務器,分別負責一部分集羣數據的服務。好比集羣共享數據達到1G個對象,若是用5臺服務器作分片,每一臺服務器能夠負責2千萬個對象。這樣就實現了Terracotta服務器的負載均衡。這種數據分片的策略,也就是說哪一個數據對象保存在哪一個服務器上,對開發人員和實施維護人員是徹底透明的。當服務器吞吐量不能知足要求的時候,用戶能夠考慮修改代碼,對共享數據和應用系統中的數據訪問算法進行優化;也能夠簡單地增長陣列分片服務器數量。後者每每是性價比比較高的方式。用戶還能夠考慮讓兩臺服務器互爲鏡像,讓多個鏡像再組合成陣列分片。這樣每一個鏡像作到高可用性,多個鏡像在一塊兒,實現集羣性能的提升;服務器

配置Terracotta集羣
環境的準備工做(此次咱們在linux下進行,3臺服務器上進行,主節點服務器(192.168.2.11),子節點(192.168.2.十一、192.168.2.2一、192.168.2.221),如今咱們把這個代碼打jar包後放在下面配置的集羣上,讓多個JVM共同訪問一個計數器)
一、 建立tc-config.xml文件,存放到terracotta根目錄下(能夠經過config-samples文件夾下的tc-config-express-reference.xml文件進行修改),該文件是描述client節點在TC Server中行爲的惟一信息,也是咱們的程序做爲Terracotta Client節點添加時主要的內容(爲了可以讓任何節點都在不修改的狀況下都能成爲主節點,我在配置文件中配置了一些冗餘的信息,以及在每一個節點都創建了相同的文件夾):
每一個節點都有紅框中的文件夾網絡

配置文件(一個完整的tx-config.xml文件,附帶有文件屬性說明,每一個節點內容都同樣,建立好後,能夠直接拷貝到其餘節點):

<?xml version="1.0" encoding="UTF-8" ?>  
<tc:tc-config xmlns:tc="http://www.terracotta.org/config"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="http://www.terracotta.org/schema/terracotta-6.xsd">  
    <!-- # 配置TERRACOTTA CLUSTER的優化屬性,能夠放在這裏,也能夠放在TC.PROPERTIES文件中,TERRACOTTA依如下次序讀取屬性配置   
        # 一、安裝JAR # 二、本XML文件的tc-config節 # 三、tc.properties文件 # 四、系統屬性定義 -->  
    <tc-properties>  
        <!--   
            <property name="l1.cachemanager.percentageToEvict" value="10"/>   
            <property name="l1.cachemanager.sleepInterval" value="3000"/>   
            <property name="l1.cachemanager.criticalThreshold" value="90"/>   
            <property name="l1.cachemanager.threshold" value="70"/>   
            <property name="l1.cachemanager.monitorOldGenOnly" value="true"/>   
        -->  
        <property name="l2.nha.dirtydb.autoDelete" value="true" />  
        <property name="l1.cachemanager.enabled" value="true" />  
        <property name="logging.maxLogFileSize" value="1024" />  
    </tc-properties>  
    <!-- SYSTEM這一節記錄一些影響Terracotta全局的數據 -->  
    <system>  
        <!--default:development can setup "production" -->  
        <configuration-model>development</configuration-model>  
    </system>  
    <!--   
        Servers節點內,用來指定Servers Array裏全部服務器,TC Server經過子節點<dso-port>來配置服務監聽端口爲9510,  
        使TC client與DSO模式協同工做   
    -->  
    <servers>  
        <server host="192.168.2.11" name="oraclerac1"  
            bind="192.168.2.11">  
            <!--當配置以持久方式(persistent)保存數據時候的數據存放地址-->  
            <data>/usr/java/terracotta/server-data</data>  
            <!--日誌存放地址-->  
            <logs>/usr/java/terracotta/server-logs</logs>  
            <index>/usr/java/terracotta/server-index</index>  
            <!--供客戶端調用的端口-->  
            <dso-port>9510</dso-port>  
            <!--供jmx調用的端口-->  
            <jmx-port>9520</jmx-port>  
            <!--server間的監聽端口-->  
            <l2-group-port>9530</l2-group-port>  
            <!--   
                一個空的<authentication/>表明使用JAVA默認的JMX認證方式,須要修改:$JAVA_HOME/jre/lib/management/jmxremote.password  
                增長一行 用戶 密碼 #   
                $JAVA_HOME/jre/lib/management/jmxremote.access,   
                增長一行 用戶 readwrite # 同時要執行 #   
                一、chmod 500 jmxremote.password   
                二、chown <啓動TC-SERVER的用戶>   
                jmxremote.password   
            -->  
            <authentication />  
            <!--   
                # 定義terracotta http server 訪問用戶管理文件名,文件格式爲 # username: password [,rolename ...]   
                # rolename目前只有statistics,容許收集統計數據   
                <http-authentication> <user-realm-file>/usr/java/terracotta/realm.properties</user-realm-file>   
                </http-authentication> -->  
            <dso>  
                <!--  
                    定義在server 啓動後多少秒內,能夠鏈接?  
                -->  
                <client-reconnect-window>120</client-reconnect-window>  
                <!--   
                    定義DSO對象的持久性保存方式 # temporary-swap-only-方式只臨時使用下磁盤,比permanent-store方式要快些   
                    # permanent-store-方式只有變化當即寫入磁盤,更有利於SERVER異常後的數據恢復。   
                    # 默認爲temporary-swap-only方式   
                -->  
                <persistence>  
                    <mode>permanent-store</mode>  
                </persistence>  
                <garbage-collection>  
                    <!--  
                        配置分佈式JVM垃圾的回收方式,true表明自動回收,false模式下只有在'run-dgc'腳本被調用的狀況纔回收  
                    -->  
                    <enabled>true</enabled>  
                    <!-- 配置爲TRUE在分佈式垃圾回收的時候是否寫額外信息到日誌中,有利於系統優化 -->  
                    <verbose>false</verbose>  
                    <!-- 分佈式垃圾回收時間間隔,單位秒 -->  
                    <interval>3600</interval>  
                </garbage-collection>  
            </dso>  
        </server>  
        <server host="192.168.2.21" name="oraclerac2">  
            <data>/usr/java/terracotta/server-data</data>  
            <logs>/usr/java/terracotta/server-logs</logs>  
            <index>/usr/java/terracotta/server-index</index>  
            <dso-port>9510</dso-port>  
            <jmx-port>9520</jmx-port>  
            <l2-group-port>9530</l2-group-port>  
            <authentication />  
            <dso>  
                <client-reconnect-window>120</client-reconnect-window>  
                <persistence>  
                    <mode>permanent-store</mode>  
                </persistence>  
                <garbage-collection>  
                    <enabled>true</enabled>  
                    <verbose>false</verbose>  
                    <interval>3600</interval>  
                </garbage-collection>  
            </dso>  
        </server>  
        <server host="192.168.2.221" name="dataguard">  
            <data>/usr/java/terracotta/server-data</data>  
            <logs>/usr/java/terracotta/server-logs</logs>  
            <index>/usr/java/terracotta/server-index</index>  
            <dso-port>9510</dso-port>  
            <jmx-port>9520</jmx-port>  
            <l2-group-port>9530</l2-group-port>  
            <authentication />  
            <dso>  
                <client-reconnect-window>120</client-reconnect-window>  
                <persistence>  
                    <mode>permanent-store</mode>  
                </persistence>  
                <garbage-collection>  
                    <enabled>true</enabled>  
                    <verbose>false</verbose>  
                    <interval>3600</interval>  
                </garbage-collection>  
            </dso>  
        </server>  
        <ha>  
            <!--下面的mode咱們選用了networked-active-passive方式, 表示DSO數據是存放在不一樣的TC Serer上的,  
                數據的同步經過 網絡數據來交換完成,該模式下的active和passive其實是經過 狀態檢查和投票產生的,  
                而另一種方式disk-based-active-passive表示 TC serers的DSO數據是存放在同一個存儲設備上的,  
                不一樣的TC serers 經過網絡文件系統等方式在配置文件的<data>屬性中被引用,該模式下的active和   
                passive是經過disk lock來完成的   
            -->  
            <mode>networked-active-passive</mode>  
            <networked-active-passive>  
                <!--心跳檢查間隔,單位秒-->  
                <election-time>5</election-time>  
            </networked-active-passive>  
        </ha>  
        <update-check>  
            <!--運行時候是否進行Terracotta版本檢查,會鏈接Terracotta.org-->  
            <enabled>true</enabled>  
            <!--檢查間隔天數,默認爲7-->  
            <period-days>10</period-days>  
        </update-check>  
    </servers>  
    <!--設置影響全部鏈接到系統的client-->  
    <clients>  
        <!--告訴dso把TC client的日誌放在哪裏,可使用參數 %h表明hostname, %i表明IP地址,  
            默認爲啓動client的目錄的相對目錄,也可使用絕對路徑-->  
        <logs>/usr/java/terracotta/client-logs/pojo/%i</logs>  
    </clients>  
    <application>  
        <dso>  
            <!-- 定義那些class應該有terracotta來構建,即應該在jvm進行cluster和共享,能夠經過定義包含(include)及 排除  
                (exclude)兩種方式來配置   
            -->  
            <instrumented-classes>  
                <!--添加自定義的對象/類被共享,可是這個類中有的字段是被描述成"transient"的,仍是應該 保持"transient"字段應有的特性,  
                    經過設置<honor-transient>爲'true',已經聲明成"transient"的 字段他們的狀態和值不會在不一樣應用的實例間可用,只有本地的  
                    應用實例能夠建立,讀,寫這些字段, 若是應用程序有對其依賴的包,此處還需進行添加  
                -->  
                <include>  
                    <class-expression>  
                        yale.terracotta.demo.TerracottaDemo  
                    </class-expression>  
                    <!--若是設置爲false,那麼全部標示爲臨時對象(transient)的類都要求使用terracotta來構建-->  
                    <honor-transient>true</honor-transient>  
                    <!-- 定義在裝載類時候要執行的動做: 若是是java類方法,使用method,注意method不能有參數,調用腳本,  
                        使用execute 若是配置了onload,那麼method和execute 2者必須配置一種   
                        <on-load><method></method></on-load>   
                    -->  
                </include>  
            </instrumented-classes>  
            <!--   
                列出臨時屬性field,即不須要在cluster、shared的屬性列表   
                <transient-fields> <field-name>xx.yy.zz</field-name>   
                <field-name>xx.yy.zz</field-name> </transient-fields>   
            -->  
            <!-- 告知DSO哪些應用在你的web容器中使用DSO,對於session內共享對象是否使用auto-lock模式自動進行管理,   
                能夠經過設置session-locking值來決定,若是設置爲false,就不進行auto-lock自動模式管理,而是須要應用進行控制,  
                但不管哪一種模式,經過HttpSession對象進行操做,好比setAttribute(), setMaxInactiveInterval()仍然自動會鎖  
                <web-applications>   
                <web-application>yale_app</web-application>   
                <web-application session-locking="false">yale_app1</web-application>   
                </web-applications>  
            -->  
            <roots>  
                <root>  
                    <!--變爲全局變量-->  
                    <field-name>  
                        yale.terracotta.demo.TerracottaDemo.demo  
                    </field-name>  
                    <!--   
                        <root-name></root-name>   
                        <distributed-methods>  
                        <method-expression></method-expression>  
                        </distributed-methods>  
                        使這些字段「transient」,這樣這些值就只能在本地上是可用的   
                        <transient-fields>  
                        <field-name></field-name>  
                        </transient-fields>   
                    -->  
                </root>  
            </roots>  
            <!--   
                分佈式方法調用,當某個method在一個JVM被調用後,整個cluster下jvm都調用此method,經常使用於事件監聽   
                <distributed-methods> 設置爲false,那麼只有在method歸屬對象在jvm已經建立,method才被調用,默認爲true   
                <method-expression run-on-all-nodes="false">xx.yy.zz</method-expression>   
                </distributed-methods>   
            -->  
            <!--   
                能夠經過將應用放在同一應用組中來共享class,但必須將應用放在不一樣Terracotta節點中, 好比放在不一樣web server實例中,  
                目前Terracotta不支持在同一節點中共享不一樣應用的class 同時能夠經過named-classloader指定class 裝載類  
                <app-groups>   
                <app-group name="petstore-group">   
                <web-application>yale_app</web-application>   
                <web-application>yale_app1</web-application>   
                <named-classloader>Standard.system</named-classloader>   
                </app-group>   
                </app-groups>   
            -->  
            <!-- 默認爲TURE,啓用 mutations方式來影射共享對象 <dso-reflection-enabled>true</dso-reflection-enabled> -->  
            <!-- 本節用於設置自定義的鎖,鎖能夠分爲自動鎖(autolock)和命名鎖(named-lock) # 鎖的級別能夠分爲:  
                # 一、寫鎖write # 二、同步寫鎖synchronous-write # 三、讀鎖read # 四、併發鎖 concurrent # 其中併發鎖必定要當心使用,  
                併發容許同時寫一個對象。 -->  
            <locks>  
                <!-- 對一個已經聲明爲共享的對象進行操做,告訴DSO,當調用這些對象的時候,  
                    假設給它加上 了一把持久的鎖。 autolock鎖能夠將你指望的方法,經過java的同步機制(block和method)來進行管理,   
                    對於沒有定義爲synchronized的對象,須要設置auto-synchronized=true,好比<autolock auto-synchronized=true> name-lock   
                    徹底依賴於java的synchronization機制,能夠對鎖進行命名以方便管理 例子中給TerracottaDemo.run()方法定義了自動鎖(autolock)。  
                    他告訴Teraccotta當這個方法對共享的數據加鎖的時候(TerracottaDemo.yale對象是共享的),使得這個鎖在整個集羣範圍內生效。  
                    這樣一來集羣中任何一個線程鎖住這個對象的時候,其它任何線程都要等這個鎖解除 後才能訪問被保護的數據(TerracottaDemo.count)。  
                    這樣計數器的訪問也就在整個集羣中獲得了保護   
                -->  
                <autolock>  
                    <method-expression>  
                        void yale.terracotta.demo.TerracottaDemo.run()  
                    </method-expression>  
                    <lock-level>write</lock-level>  
                </autolock>  
            </locks>  
        </dso>  
    </application>  
</tc:tc-config>  

 


 二、 拷貝tc-config.xml(上面已經存在該文件了)文件到各個linux服務器上(存放在terracotta根目錄下)
 三、 把上面的線程的代碼例子打成jar包,拷貝到各個linux服務器上(存放在terracotta根目錄下)

 

 

 

主節點操做如下命令(192.168.2.11):
進入到$TC_HOME/bin目錄,執行start-tc-server.sh,未執行參數-f<tc-config.xml>啓動時,啓動程序會使用tc.jar包裏自帶的默認配置文件’com/tc/config/schema/setup/default-config.xml’:

 

咱們不採用上面的啓動方式,咱們啓動指定的配置文件:

咱們能夠看到terracotta server已經啓動成功

子節點操做如下命令(192.168.2.十一、192.168.2.2192.168.2.221):
咱們依次啓動3個子節點服務器後,能夠看到控制檯打印的結果(控制檯顯示客戶端已經成功鏈接到服務器192.168.2.11:9510,咱們能夠看到計數器仍然在累加,在全局範圍內共享):

 

 

可見計數器已經在集羣中被3個Java程序實例所共享。每一個程序有兩個線程訪問計數器。這樣整個集羣中實際上有6個線程在同時累加計數器, 從上面能夠看到,整個Java代碼沒有做任何改動。只是增長了一個tc-config.xml文件,從tc-config.xml文件中的配置內容能夠看出,terracotta仍是作了不少的工做的,並且已經比較完善,其實無論它是結合本身的產品ehcache、quartz進行整合,仍是結合apache下的相關產品進行整合,terracotta能夠整合的產品較多,所以咱們也沒有必要一個一個去搭建,它們的整合過程只是在配置的方式上有所不一樣,其實咱們在深刻了解它的原理後在進行其餘產品的整合,其實都是一個簡單的過程。

相關文章
相關標籤/搜索