zookeeper是一個分佈式的,開放源碼的分佈式應用程序協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。它是一個爲分佈式應用提供一致性服務的軟件,由於產品升級拓展,pom等文件配置越來越複雜,因此zk派上用場。
一.zookeeper簡介
一款管理分佈式應用程序的協調服務系統
二.zookeeper應用場景
網上也有很多介紹,可以參見 http://blog.csdn.net/xinguan1267/article/details/38422149
本文主要介紹基於java的客戶端開發
三.基於JAVA客戶端實戰
3.1Client
// 創建一個與服務器的連接 需要(服務端的 ip+端口號)(session過期時間)(Watcher監聽註冊)
ZooKeeper zk = new ZooKeeper("10.154.156.180:2181",
3000, new Watcher() {
// 監控所有被觸發的事件
public void process(WatchedEvent event) {
// TODO Auto-generated method stub
System.out.println("已經觸發了" + event.getType() + "事件!");
}
});
// 創建一個目錄節點
/**
* CreateMode:
* PERSISTENT (持續的,相對於EPHEMERAL,不會隨着client的斷開而消失)
* PERSISTENT_SEQUENTIAL(持久的且帶順序的)
* EPHEMERAL (短暫的,生命週期依賴於client session)
* EPHEMERAL_SEQUENTIAL (短暫的,帶順序的)
*/
zk.create("/testRootPath", "testRootData".getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
// 創建一個子目錄節點
zk.create("/testRootPath/testChildPathOne", "testChildDataOne".getBytes(),Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
System.out.println(new String(zk.getData("/testRootPath",false,null)));
// 取出子目錄節點列表
System.out.println(zk.getChildren("/testRootPath",true));
// 創建另外一個子目錄節點
zk.create("/testRootPath/testChildPathTwo", "testChildDataTwo".getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
System.out.println(zk.getChildren("/testRootPath",true));
// 修改子目錄節點數據
zk.setData("/testRootPath/testChildPathOne","hahahahaha".getBytes(),-1);
byte[] datas = zk.getData("/testRootPath/testChildPathOne", true, null);
String str = new String(datas,"utf-8");
System.out.println(str);
//刪除整個子目錄 -1代表version版本號,-1是刪除所有版本
zk.delete("/testRootPath/testChildPathOne", -1);
System.out.println(zk.getChildren("/testRootPath",true));
System.out.println(str);
3.2Curator
Curator框架提供了一套高級的API, 簡化了ZooKeeper的操作。 它增加了很多使用ZooKeeper開發的特性,可以處理ZooKeeper集羣複雜的連接管理和重試機制。 這些特性包括:
封裝ZooKeeper client與ZooKeeper server之間的連接處理;
提供了一套Fluent風格的操作API;
提供ZooKeeper各種應用場景(recipe, 比如共享鎖服務, 集羣領導選舉機制)的抽象封裝.
關於Fluent風格可以查看我的一篇博客(建造者模式),在偶看es搜索源碼時發現也使用了Fluent風格。
如下是使用Curator創建對象的方法
public static CuratorFramework createWithOptions(String connectionString, RetryPolicy retryPolicy, int connectionTimeoutMs, int sessionTimeoutMs) {
return CuratorFrameworkFactory.builder().connectString(connectionString)
.retryPolicy(retryPolicy)
.connectionTimeoutMs(connectionTimeoutMs)
.sessionTimeoutMs(sessionTimeoutMs)
.build();
}
調用代碼如下:
client = createWithOptions("10.154.156.180:2181", new ExponentialBackoffRetry(1000, 3), 1000, 1000);
client.start();
如果需要創建新目錄節點 依然是Fluent風格
client.create().forPath("/curator", new byte[0]);
當然創建zk也可以不使用Fluent風格
public static CuratorFramework createSimple(String connectionString) {
ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3);
return CuratorFrameworkFactory.newClient(connectionString, retryPolicy);
}
其他方法說明:
create(): 發起一個create操作. 可以組合其他方法 (比如mode 或background) 最後以forPath()方法結尾
delete(): 發起一個刪除操作. 可以組合其他方法(version 或background) 最後以forPath()方法結尾
checkExists(): 發起一個檢查ZNode 是否存在的操作. 可以組合其他方法(watch 或background) 最後以forPath()方法結尾
getData(): 發起一個獲取ZNode數據的操作. 可以組合其他方法(watch, background 或get stat) 最後以forPath()方法結尾
setData(): 發起一個設置ZNode數據的操作. 可以組合其他方法(version 或background) 最後以forPath()方法結尾
getChildren(): 發起一個獲取ZNode子節點的操作. 可以組合其他方法(watch, background 或get stat) 最後以forPath()方法結尾
inTransaction(): 發起一個ZooKeeper事務. 可以組合create, setData, check, 和/或delete 爲一個操作, 然後commit() 提交