2011年11月8日 星期二

Terracotta : DSO(Distributed Shared Objects)

最近在玩Apache lucene , 針對一個IndexWriter在建立的時候只能有一個instance(同一個index folder) , 在multi-thread的時候可以把這個Instance create好丟出去給全部用,這沒什麼問題,我碰到的狀況是如果有2台機器要同時對一個index folder create indexWriter時就會出錯了,那有沒有什麼辦法能讓2台機器上的indexWriter共用(這不能算是好辦法,因為會有writer close的問題..lol).

找到的東西就是 Terracotta , Terracotta 是一個JVM-level clustering 目前最新的Open source版本是3.5.3, terracotta可以做很多的事, 這邊只做簡單的測試,主要是針對Terracotta 的DSO 功能。

有關DSO的說明跟細節可以參考 About Terracotta DSO Installations

首先要先下載Open Source版本的Terracotta 3.5.3, 可以到官網下載,這邊我下載的是binary 版本,然後將其解壓縮到Linux 機器上, 這邊都用預設的設定, 如果沒有自訂tc-config.xml 的話,預設會用com/tc/config/setup/default-config.xml來啟動Terracotta server, 這邊我只設定單台的tc server , Terracotta 支持Server Array , 可以多個tc server成為group , 當root死掉時會將root 交給其他active 的server , 有興趣可以自己看看官網的文件, The Terracotta Server Array , 下圖是terracotta server啟動的狀況



這樣tc server就算啟動完成, 再來是要寫一個簡單的sample 來測試, 這邊可以先安裝
Terracotta DSO Eclipse Plugin , 然後在Eclipse 裡面直接new 一個DSO project , 如下圖




然後寫一個簡單的Java 程式測試,

package com;

import java.util.Random;


public class DsoTest {
 private Integer shareInteger = new Random().nextInt();

 public Integer getShareInteger() {
  System.out.println("getShareInteger on call !!");
  return shareInteger;
 }

 public void setShareInteger(Integer shareInteger) {
  System.out.println("set value!!!");
  this.shareInteger = shareInteger;
 }
 
 public void print(){
  System.out.println("shareInteger = "   shareInteger.toString());
 }
 
 
 public static void main(String[] args) {
  DsoTest t1 = new DsoTest();
  t1.print();
  
  DsoTest t2 = new DsoTest();
  t2.print();
 }
}


執行後結果如下








這個是我們預期的結果,那如果加上terracotta之後呢?
先打開tc-config.xml做設定
<?xml version="1.0" encoding="UTF-8"?>
<con:tc-config xmlns:con="http://www.terracotta.org/config">
  <servers>
    <server host="192.168.3.95" name="EMD-test">
      <dso-port bind="192.168.3.95">9510</dso-port>
      <jmx-port bind="192.168.3.95">9520</jmx-port>
      <data>root/terracotta/server-data</data>
      <logs>root/terracotta/server-logs</logs>
      <statistics>root/terracotta/cluster-statistics</statistics>
    </server>
  </servers>
  <clients>
    <logs>terracotta/client-logs</logs>
  </clients>
  <application>
    <dso>
      <instrumented-classes>
        <include>
          <class-expression>com.*..*</class-expression>
        </include>
      </instrumented-classes>
      <roots>
        <root>
          <field-name>com.DsoTest.shareInteger</field-name>
        </root>
      </roots>
    </dso>
  </application>
</con:tc-config>
主要的是root 跟 field-name , 然後再加上instrumented-classes的部份, 這樣設定之後再去跑一次,
直接run as > terracotta dso application


這次看到的結果就是一樣的instance了


這邊只是單純簡單試試DSO的功能,確實是可以達到JVM-Level 的cluster ,也許那天會用上也不一定。



Reference :

Terracotta Cluster : Wiki
Introduction to Terracotta DSO
JVM-level clustering - Terracotta
用Terracotta 去Distribute Objects