分佈式助手Zookeeper
Zookeeper的Session:
(1)客戶端和server間採用長連接
(2)連接建立後,server產生session ID(64位)返還給客戶端
(3)客戶端定期發送ping包來檢查和保持和server的連接
(4)一旦session結束或超時,所有ephemeral節點會被刪除
(5)客戶端可根據情況設置合適的session超時時間
Zookeeper的Watchs:
Watch是客戶端安裝在server的事件偵聽方法
(1) 當偵聽的變化發生時,server發消息給客戶端進行通知
(2) 客戶端使用單線程對所有事件按順序同步回調
(3) 觸發回調條件:
• 客戶端連接、斷開連接
• 節點數據發生改變
• 節點本身發生變化
(4)Watch是單發的,每次觸發後會被自動刪除
(5)如果需要再次偵聽事件,必須重新安裝watch
(6)無法保證跟蹤到每一個變化
(7)避免安裝大量watches偵聽在同一個節點
Zookeeper的一些注意事項:
在客戶端事件回調實現有阻塞調用
• 試圖跟蹤每個狀態變化
• 大量watch偵聽同一個znode的狀態變化
• 客戶端會有需要長時間處理的GC(garbage collection)
• Session超時後上層應用不進行恢復處理
可以把zookper看成一個文件系統,文件系統中的所有文件形成一個數狀結構,zookeeper維護着這樣的樹形層次結構,樹中的節點稱爲znode。每個znode有一個與之相關聯的ACL(Access Control List)
znode通過路徑被引用,而且要採用絕對路徑,即必須以/開頭。znode存儲的數據要小於1M,這個可以配置,建議不要存儲太大的東西,避免同步操作時間過長。
znode類型
短暫znode:回話結束,zookeeper就會把短暫znode刪除,短暫znode不可以有子節點。
持久znode:回話結束也不會被刪除,除非客戶端明確要刪除此znode,持久znode可以有子節點。
對於在特定時刻需要知道有哪些分佈式資源可用的應用來說,使用短暫znode比較合適。
znode的觀察機制
znode以某種方式發生變化時,“觀察”(watch)機制可以讓客戶端得到通知。可以針對ZooKeeper服務的“操作”來設置觀察,該服務的其他操作可以觸發觀察。比如,客戶端可以對某個客戶端調用exists操作,同時在它上面設置一個觀察,如果此時這個znode不存在,則exists返回false,如果一段時間之後,這個znode被其他客戶端創建,則這個觀察會被觸發,之前的那個客戶端就會得到通知。
zookeeper的一些基本操作如下:
<table class="bbcode"><tr><td>操作</td><td>描述<tr><td>create</td><td>創建一個znode(必須有父節點)<tr><td>delete</td><td>刪除一個znode(該znode不能有任何子節點)<tr><td>exists</td><td>測試一個znode是否存在,並且查詢它的元數據<tr><td>getACL,setACL</td><td>獲取/設置一個znode的ACL<tr><td>getChildren</td><td>獲取一個znode的子節點名字列表<tr><td>getData,setData</td><td>獲取/設置一個znode所保存的數據<tr><td>sync</td><td>將客戶端的znode視圖與ZooKeeper服務端同步</table>
Zookeeper中的更新操作是有條件的。在使用delete或者setData操作時必須提供被更新znode的版本號,如果版本號不匹配,則更新操作失敗。一般情況下設置-1即可。
API
目前主要有java和C兩種客戶端,每種操作都有同步和異步兩種執行方式。
觀察觸發器
可以設置觀察的操作:exists,getChildren,getData
可以觸發觀察的操作:create,delete,setData
下面給出一些事件截圖:
NodeCreated:節點創建事件
NodeDeleted:節點被刪除事件
NodeDataChanged:節點數據改變事件
NodeChildrenChanged:節點的子節點改變事件
下面我們再來看下ACL(zookeeper的訪問控制列表),每個znode被創建時都會帶有一個ACL列表,用於決定誰可以對它執行何種操作。
<table class="bbcode"><tr><td>ACL權限</td><td>允許的操作<tr><td>CREATE</td><td>創建節點create("name")<tr><td>READ</td><td>getChildren() getData()<tr><td>WRITE</td><td>setData<tr><td>DELETE</td><td>delete("name")刪除節點<tr><td>ADMIN</td><td>setACL()設置權限</table>
每個ACL都是身份驗證模式、符合該模式的一個身份和一組權限的組合。身份驗證模式有三種:
digest:用戶名,密碼
host:通過客戶端的主機名來識別客戶端
ip: 通過客戶端的ip來識別客戶端
所以我們可以類似這樣構建一個ACL類:
new ACL(Perms.READ,new Id("host","example.com"));
這個ACL對應的身份驗證模式是host
符合該模式的身份是example.com
權限的組合是:READ
下面給出一個API連接zookeeper的示例:
<pre name="code" class="java">package com.util;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
/**
* 測試zookeeper的連接
* @author 三劫散仙
*
* ***/
public class Test {
public static void main(String[] args)throws Exception {
ZooKeeper zk=new ZooKeeper("10.2.143.5:2181", 5000, new Watcher() {
CountDownLatch down=new CountDownLatch(1);//同步阻塞狀態
@Override
public void process(WatchedEvent event) {
if(event.getState()==Event.KeeperState.SyncConnected){
down.countDown();//連接上之後,釋放計數器
}
}
});
System.out.println("連接成功:"+zk.toString());
zk.close();//關閉連接
}
}
</pre>
打印效果如下:
<pre name="code" class="java">連接成功:State:CONNECTING sessionid:0x0 local:null remoteserver:null lastZxid:0 xid:1 sent:0 recv:0 queuedpkts:0 pendingresp:0 queuedevents:0
</pre>
(1)客戶端和server間採用長連接
(2)連接建立後,server產生session ID(64位)返還給客戶端
(3)客戶端定期發送ping包來檢查和保持和server的連接
(4)一旦session結束或超時,所有ephemeral節點會被刪除
(5)客戶端可根據情況設置合適的session超時時間
Zookeeper的Watchs:
Watch是客戶端安裝在server的事件偵聽方法
(1) 當偵聽的變化發生時,server發消息給客戶端進行通知
(2) 客戶端使用單線程對所有事件按順序同步回調
(3) 觸發回調條件:
• 客戶端連接、斷開連接
• 節點數據發生改變
• 節點本身發生變化
(4)Watch是單發的,每次觸發後會被自動刪除
(5)如果需要再次偵聽事件,必須重新安裝watch
(6)無法保證跟蹤到每一個變化
(7)避免安裝大量watches偵聽在同一個節點
Zookeeper的一些注意事項:
在客戶端事件回調實現有阻塞調用
• 試圖跟蹤每個狀態變化
• 大量watch偵聽同一個znode的狀態變化
• 客戶端會有需要長時間處理的GC(garbage collection)
• Session超時後上層應用不進行恢復處理
可以把zookper看成一個文件系統,文件系統中的所有文件形成一個數狀結構,zookeeper維護着這樣的樹形層次結構,樹中的節點稱爲znode。每個znode有一個與之相關聯的ACL(Access Control List)
znode通過路徑被引用,而且要採用絕對路徑,即必須以/開頭。znode存儲的數據要小於1M,這個可以配置,建議不要存儲太大的東西,避免同步操作時間過長。
znode類型
短暫znode:回話結束,zookeeper就會把短暫znode刪除,短暫znode不可以有子節點。
持久znode:回話結束也不會被刪除,除非客戶端明確要刪除此znode,持久znode可以有子節點。
對於在特定時刻需要知道有哪些分佈式資源可用的應用來說,使用短暫znode比較合適。
znode的觀察機制
znode以某種方式發生變化時,“觀察”(watch)機制可以讓客戶端得到通知。可以針對ZooKeeper服務的“操作”來設置觀察,該服務的其他操作可以觸發觀察。比如,客戶端可以對某個客戶端調用exists操作,同時在它上面設置一個觀察,如果此時這個znode不存在,則exists返回false,如果一段時間之後,這個znode被其他客戶端創建,則這個觀察會被觸發,之前的那個客戶端就會得到通知。
zookeeper的一些基本操作如下:
<table class="bbcode"><tr><td>操作</td><td>描述<tr><td>create</td><td>創建一個znode(必須有父節點)<tr><td>delete</td><td>刪除一個znode(該znode不能有任何子節點)<tr><td>exists</td><td>測試一個znode是否存在,並且查詢它的元數據<tr><td>getACL,setACL</td><td>獲取/設置一個znode的ACL<tr><td>getChildren</td><td>獲取一個znode的子節點名字列表<tr><td>getData,setData</td><td>獲取/設置一個znode所保存的數據<tr><td>sync</td><td>將客戶端的znode視圖與ZooKeeper服務端同步</table>
Zookeeper中的更新操作是有條件的。在使用delete或者setData操作時必須提供被更新znode的版本號,如果版本號不匹配,則更新操作失敗。一般情況下設置-1即可。
API
目前主要有java和C兩種客戶端,每種操作都有同步和異步兩種執行方式。
觀察觸發器
可以設置觀察的操作:exists,getChildren,getData
可以觸發觀察的操作:create,delete,setData
下面給出一些事件截圖:
NodeCreated:節點創建事件
NodeDeleted:節點被刪除事件
NodeDataChanged:節點數據改變事件
NodeChildrenChanged:節點的子節點改變事件
下面我們再來看下ACL(zookeeper的訪問控制列表),每個znode被創建時都會帶有一個ACL列表,用於決定誰可以對它執行何種操作。
<table class="bbcode"><tr><td>ACL權限</td><td>允許的操作<tr><td>CREATE</td><td>創建節點create("name")<tr><td>READ</td><td>getChildren() getData()<tr><td>WRITE</td><td>setData<tr><td>DELETE</td><td>delete("name")刪除節點<tr><td>ADMIN</td><td>setACL()設置權限</table>
每個ACL都是身份驗證模式、符合該模式的一個身份和一組權限的組合。身份驗證模式有三種:
digest:用戶名,密碼
host:通過客戶端的主機名來識別客戶端
ip: 通過客戶端的ip來識別客戶端
所以我們可以類似這樣構建一個ACL類:
new ACL(Perms.READ,new Id("host","example.com"));
這個ACL對應的身份驗證模式是host
符合該模式的身份是example.com
權限的組合是:READ
下面給出一個API連接zookeeper的示例:
<pre name="code" class="java">package com.util;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
/**
* 測試zookeeper的連接
* @author 三劫散仙
*
* ***/
public class Test {
public static void main(String[] args)throws Exception {
ZooKeeper zk=new ZooKeeper("10.2.143.5:2181", 5000, new Watcher() {
CountDownLatch down=new CountDownLatch(1);//同步阻塞狀態
@Override
public void process(WatchedEvent event) {
if(event.getState()==Event.KeeperState.SyncConnected){
down.countDown();//連接上之後,釋放計數器
}
}
});
System.out.println("連接成功:"+zk.toString());
zk.close();//關閉連接
}
}
</pre>
打印效果如下:
<pre name="code" class="java">連接成功:State:CONNECTING sessionid:0x0 local:null remoteserver:null lastZxid:0 xid:1 sent:0 recv:0 queuedpkts:0 pendingresp:0 queuedevents:0
</pre>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.