zookeeperによる静的データセンター化構成管理


zookeeperによる静的データセンター化構成管理
    各プロジェクトには静的データ構成があり、これらのデータプラットフォームの変化は少なく、パフォーマンスを向上させるためにキャッシュ方式でデータをキャッシュするのが一般的です.分散キャッシュを使用する場合は、ネットワークコストが高くて適切ではありません.
一般的にローカルキャッシュを採用し、シングルマシン環境でキャッシュデータを修正する方式は比較的簡単で、データベースを更新すると同時に、ローカルキャッシュを更新することも修正するが、クラスタモードではこんなに簡単ではなく、最も簡単で直接的である.
1台のサーバなどを修正する方法で、時間と労力がかかります.あるいはjmsメッセージ同期によって処理され、具体的にはあまり説明されていない.ここではzookeeperを用いて実現する別の方法を紹介する.
静的データセンター化構成管理.
    まずzookeeperを簡単に紹介します.ZooKeeperは最近人気のあるPaxosアルゴリズムの実現であり、Hadoopの下のサブプロジェクトでもあり、Google Chubbyのオープンソース版とされています.
主に分散環境で分散ロック、構成管理、名前サービス、グループサービスを提供するために使用されます.高い可用性、安定性、信頼性を備えています.分散アプリケーションではスイスの軍刀のように
多くの場所で使えます.
データをキャッシュするにはHashMapオブジェクトが必要ですが、JDKのHashMapでは分散環境同期データはサポートされていません.そのためにはzookeeperと組み合わせてHashMapを再実現する必要があります.
名前はZKHashMapです.zookeeperサーバに接続されているクライアントのいずれかがZKHashMapを変更しました.zookeeperサーバを介して、zookeeperサーバに接続されている他のクライアントにアクティブに同期できます.
検索により、menagerie(https://github.com/openUtility/menagerie).公式サイトの説明:Menagerie is an implementation of the
Java Concurrency Libraries based on the popular Apache ZooKeeper.主な機能は,分散集合,分散キュー,分散ロックの実現である.興味があればソースを勉強してもいいです.
その効果を示すために、テストを行います.コードは以下の通りです.
public class TestZKHashMap {
	private static final String hostString = "localhost:2181";
	private static final String baseHashMapPath = "/test-maps";
	private static final String baseLockPath = "/test-locks";
	private static final String Init_Done = "/initData";
	private static final int timeout = 2000;

	private static ZooKeeper zk1, zk2;
    private static ZkSessionManager zkSessionManager1, zkSessionManager2;
    private static ZkHashMap<String,Person> testMap1, testMap2;
    private static Serializer<Entry<String, Person>> serializer = new JavaSerializer<String, Person>();
	
    public static void main(String[] args) throws Exception {
    	setup();
    	final CountDownLatch latch = new CountDownLatch(2);
		
		Thread thread1 = new Thread() {
			@Override
			public void run() {
				initData(zk1, zkSessionManager1);
				String znode = "test1";
				Person person = new Person("melin"); 
				testMap1.put(znode, person);
				latch.countDown();
			}
		};

		Thread thread2 = new Thread() {
			@Override
			public void run() {
				initData(zk2, zkSessionManager2);
				String znode = "test2";
				Person person = new Person("melin"); 
				testMap2.put(znode, person);
				latch.countDown();
			}
		};
		thread1.start();
		thread2.start();
		latch.await();
		Thread.sleep(100);

		if(testMap1.containsKey("test2")) {
			System.out.println("testMap1    test2");
		}
		
		if(testMap2.containsKey("test1")) {
			System.out.println("testMap2    test1");
		}
		
		tearDown();
	}
	
	private static ZooKeeper newZooKeeper() throws IOException {
        return new ZooKeeper(hostString, timeout,new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println("+++++++++"+event);
            }
        });
    }
	
	public static void setup() throws Exception {
        zk1 = newZooKeeper();
        zk1.create(baseHashMapPath,new byte[]{}, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        zkSessionManager1 = new BaseZkSessionManager(zk1);
        testMap1 = new ZkHashMap<String, Person>(baseHashMapPath, zkSessionManager1, serializer);
        
        zk2 = newZooKeeper();
        zkSessionManager2 = new BaseZkSessionManager(zk2);
        testMap2 = new ZkHashMap<String, Person>(baseHashMapPath, zkSessionManager2, serializer);
    }

    public static void tearDown() throws Exception{
        try{
        	ZkUtils.recursiveSafeDelete(zk1,baseHashMapPath,-1);
        	ZkUtils.recursiveSafeDelete(zk1,baseLockPath,-1);
        	ZkUtils.recursiveSafeDelete(zk1,Init_Done,-1);
        }catch(KeeperException ke){
            //suppress because who cares what went wrong after our tests did their thing?
        }finally{
            zk1.close();
            zk2.close();
        }
    }
    
    public static void initData(ZooKeeper zk, ZkSessionManager zkSessionManager) {
        final Lock lock = new ReentrantZkLock(baseLockPath, zkSessionManager);
        try {
        	if (null == zk.exists(Init_Done, true)) {
                // if the init_done node not exists we try to init
            	lock.lock();
            	if(zk.exists(Init_Done, true) != null) {
            		System.out.println("       "+zk);
            		return;
            	}
                System.out.println("     "+zk);
                //         ,           
                zk.create(Init_Done, null, Ids.OPEN_ACL_UNSAFE,  CreateMode.PERSISTENT);
                //    ,   
                lock.unlock();
            } else {// if init_done exists we simply load data from gcih
            	System.out.println("       "+zk);
            }
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
}

zookeeperが簡単なツリー構造モデルでPaxosアルゴリズムを実現したことに感嘆する......
資料
1:Paxosアルゴリズムの旅(一)遡及源を追う
http://rdc.taobao.com/team/jm/archives/397
2:Paxosアルゴリズム中国語翻訳
   http://wenku.baidu.com/view/87276e1dfad6195f312ba6d7.html
3:Blog:http://zoutm.iteye.com/blog/708324