當ZooKeeper集合啓動時,它會等待客戶端鏈接。客戶端將鏈接到ZooKeeper的集合的其中一個節點。它多是一個領導者或跟隨者節點。當客戶機鏈接時,該節點分配會話ID給特定的客戶端,併發送一個確認消息給客戶端。若是客戶端沒有獲得確認,它會嘗試鏈接ZooKeeper集合的另外一個節點。當鏈接到一個節點後,客戶端將以規則的間隔發送心跳到節點,以確保鏈接不會丟失。
-
若是客戶想要讀取特定的znode,它發送一個讀請求使用znode路徑的節點,所述節點從其本身的數據庫中獲取它返回所請求的znode。出於這個緣由,讀取在動物園管理員集合中速度很是快。
-
若是客戶但願將數據存儲在ZooKeeper 集合,它發送znode路徑和數據到服務器。鏈接的服務器將請求轉發到領導者,那麼領導者將從新發出書面請求到全部的追隨者。若是隻有一個數節點成功響應,接着寫請求將成功及一個成功的返回代碼將被髮送到客戶端。不然,寫請求將失敗。嚴格大部分節點被稱爲定額。
ZooKeeper集合的節點
讓咱們來分析ZooKeeper集合不一樣數量的節點的做用。
-
若是咱們有一個節點,那麼當該節點出現故障時ZooKeeper集合失敗。它有利於「單一失敗教程」,它不建議用在生產環境中。
-
若是咱們有兩個節點,一個節點出現故障,咱們也沒有「多數」,由於二分之一併非一個大多數。
-
若是咱們有三個節點及其一個節點發生故障,咱們有大多數,所以它是最低要求。它強制 ZooKeeper 集合在實際生產環境中至少有三個節點。
-
若是咱們有四個節點及其有當兩個節點失敗,它相似於有三個節點。額外的節點沒有任何做用,所以,最好是單數增長節點,例如,3, 5, 7.
咱們知道,寫處理它比在 ZooKeeper 集合讀過程是昂貴的,因爲全部的節點須要寫相同的數據在其數據庫中。所以,最好是具備節點(3,5或7)比具備大量節點的一個平衡的環境的數量少。
下圖描述了ZooKeeper 的工做流程以及在隨後的表說明了其不一樣的組件。
組件 | 描述 |
---|---|
寫入 | 寫過程是由領導節點處理。領導者轉發寫請求到全部znodes及其等待來自znodes應答。若是一半的znodes的回覆,那麼寫入過程就完成了。 |
讀取 | 讀取在內部由特定鏈接znode進行的,因此沒有必要與集羣交互。 |
複製數據庫 | 它是用來將數據存儲在zookeeper。每一個znode都有本身的數據庫及其每一個znode 在一致性的做用下,每次有相同的數據。 |
領導者(節點) | 領導者是由Znode負責處理寫請求。 |
追隨者(節點) | 追隨者收到來自客戶端的寫請求,並將其轉發到領導znode。 |
請求處理器 | 目前僅在領導節點。它從跟隨節點的請求支配寫入。 |
原子廣播 | 負責從領導節點到從節點廣播更改。 |
Zookeeper領導人選舉
讓咱們來分析一下一個領導節點在ZooKeeper集合的選舉。考慮集羣中有N多的節點。領導人選舉的過程以下 −
-
全部節點建立一個順序,znode具備相同路徑,/app/leader_election/guid_。
-
ZooKeeper 的集合將追加的10位序列號的路徑,創造了 znode 將會是 /app/leader_election/guid_0000000001, /app/leader_election/guid_0000000002, ...等。
-
對於給定的實例,它在znode建立最小數量的節點成爲領導者以及全部其餘節點的追隨者。
-
每個追隨者節點監控下一個最小號的znode。
及其該節點建立znode /app/leader_election/guid_0000000007 將監控znode /app/leader_election/guid_0000000006.
-
若是領導停機,接着其對應的znode/app/leader_electionN被刪除。
-
跟隨節點接下來將經過觀察者獲得關領導去除的通知。
-
跟隨節點接下來會檢查是否有其餘znodes用最小數量。 若是沒有,接着它將承擔領導者的角色。不然,它會找到哪些用最小數創造了znode做爲領導者的節點。
-
一樣,其餘全部跟隨節點選舉創造了znode用最小數做爲領導者的節點。
領導人選舉時,它從頭開始作一個複雜的過程。但ZooKeeper服務,使得它很是簡單。讓咱們在接下來的章節介紹 ZooKeeper 安裝和開發。
Zookeeper CLI
ZooKeeper 命令行界面(CLI)是用來與 ZooKeeper 集成做開發進行交互的。這是在調試和使用不一樣的選項時的工做有用。
爲了執行ZooKeeper的CLI操做, ZooKeeper服務器首先要啓動 (「bin/zkServer.sh start」) , 而後使用 ZooKeeper 客戶端 (「bin/zkCli.sh」). 當客戶端啓動後,能夠執行如下操做 -
- 建立znodes
- 獲取數據
- 監視 znode 變化
- 設置數據
- 建立 znode 的子 znode
- 列出一個 znode 的子 znode
- 檢查狀態
- 刪除一個 znode
如今,讓咱們一個個用一個例子地來看上面的命令。
建立Znodes
由一個給定的路徑來建立znode。flag參數指定了建立的 znode 是否爲短暫的,持久的,或連續的。默認狀況下,全部的 znodes是持久的。
-
短暫 znodes(flag: e)當會話過時或當客戶端斷開鏈接將被自動刪除。
-
連續 znodes 保證 znode 路徑是惟一的。
-
ZooKeeper集成將沿着添加序列號使用10位填充到znode路徑。例如,znode路徑 /myapp 將被轉換爲 /myapp0000000001 以及下一個序列號將是 /myapp0000000002. 若是沒有指定flag,那麼 znode 是持久的。
語法
create /path /data
示例
create /FirstZnode 「Myfirstzookeeper-app」
輸出結果
[zk: localhost:2181(CONNECTED) 0] create /FirstZnode 「Myfirstzookeeper-app」 Created /FirstZnode
要建立一個連續znode,以下圖所示添加 -s 標誌。
語法
create -s /path /data
示例
create -s /FirstZnode second-data
輸出
[zk: localhost:2181(CONNECTED) 2] create -s /FirstZnode 「second-data」 Created /FirstZnode0000000023
要建立一個臨時Znode,添加-e標誌,以下圖所示。
語法
create -e /path /data
示例
create -e /SecondZnode 「Ephemeral-data」
輸出
[zk: localhost:2181(CONNECTED) 2] create -e /SecondZnode 「Ephemeral-data」 Created /SecondZnode
記住,當丟失一個客戶端鏈接,在臨時 znode 將被刪除。能夠經過退出 ZooKeeper CLI 嘗試,而後從新打開命令行。
獲取數據
它返回 znode 的相關數據和指定 znode 元數據。這裏將獲得信息,例如當數據最後一次修改,在那裏它被修改和有關數據的信息。此外 CLI 還用於分配監視顯示通知有關的數據。
語法
get /path
示例
get /FirstZnode
輸出
[zk: localhost:2181(CONNECTED) 1] get /FirstZnode 「Myfirstzookeeper-app」 cZxid = 0x7f ctime = Tue Sep 29 16:15:47 IST 2015 mZxid = 0x7f mtime = Tue Sep 29 16:15:47 IST 2015 pZxid = 0x7f cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 22 numChildren = 0
要訪問順序znode,必須輸入znode的完整路徑。
示例
get /FirstZnode0000000023
輸出
[zk: localhost:2181(CONNECTED) 1] get /FirstZnode0000000023 「Second-data」 cZxid = 0x80 ctime = Tue Sep 29 16:25:47 IST 2015 mZxid = 0x80 mtime = Tue Sep 29 16:25:47 IST 2015 pZxid = 0x80 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 13 numChildren = 0
監視
監視顯示通知當指定znode或znode的子數據變化。只能在 get 命令中設置監視。
語法
get /path [watch] 1
示例
get /FirstZnode 1
輸出
[zk: localhost:2181(CONNECTED) 1] get /FirstZnode 1 「Myfirstzookeeper-app」 cZxid = 0x7f ctime = Tue Sep 29 16:15:47 IST 2015 mZxid = 0x7f mtime = Tue Sep 29 16:15:47 IST 2015 pZxid = 0x7f cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 22 numChildren = 0
輸出相似於正常get命令,但它會在後臺等待節點改變。
設置數據
設置指定znode的數據。當你完成設置操做,就可使用get CLI命令檢查數據。
語法
set /path /data
示例
set /SecondZnode Data-updated
輸出
[zk: localhost:2181(CONNECTED) 1] get /SecondZnode 「Data-updated」 cZxid = 0x82 ctime = Tue Sep 29 16:29:50 IST 2015 mZxid = 0x83 mtime = Tue Sep 29 16:29:50 IST 2015 pZxid = 0x82 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x15018b47db00000 dataLength = 14 numChildren = 0
若是分配監視選項在get命令(以前的命令),則輸出將相似以下 -
輸出
[zk: localhost:2181(CONNECTED) 1] get /FirstZnode 「Mysecondzookeeper-app」 WATCHER: : WatchedEvent state:SyncConnected type:NodeDataChanged path:/FirstZnode cZxid = 0x7f ctime = Tue Sep 29 16:15:47 IST 2015 mZxid = 0x84 mtime = Tue Sep 29 17:14:47 IST 2015 pZxid = 0x7f cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 23 numChildren = 0
建立子znode
建立子znode相似於建立新的znodes。惟一的區別在於,子 znode 的路徑將包含有父路徑。
語法
create /parent/path/subnode/path /data
示例
create /FirstZnode/Child1 firstchildren
輸出
[zk: localhost:2181(CONNECTED) 16] create /FirstZnode/Child1 「firstchildren」 created /FirstZnode/Child1 [zk: localhost:2181(CONNECTED) 17] create /FirstZnode/Child2 「secondchildren」 created /FirstZnode/Child2
列出子znode
該命令用於列出和顯示子 znode 。
語法
ls /path
示例
ls /MyFirstZnode
輸出
[zk: localhost:2181(CONNECTED) 2] ls /MyFirstZnode [mysecondsubnode, myfirstsubnode]
檢查狀態
狀態描述了指定znode的元數據。它包含詳細信息,如時間戳,版本號,訪問控制列表,數據長度和子znode。
語法
stat /path
示例
stat /FirstZnode
輸出
[zk: localhost:2181(CONNECTED) 1] stat /FirstZnode cZxid = 0x7f ctime = Tue Sep 29 16:15:47 IST 2015 mZxid = 0x7f mtime = Tue Sep 29 17:14:24 IST 2015 pZxid = 0x7f cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 23 numChildren = 0
刪除Znode
刪除指定znode和遞歸刪除全部的子znode。這隻有在znode可用時發生。
語法
rmr /path
示例
rmr /FirstZnode
輸出
[zk: localhost:2181(CONNECTED) 10] rmr /FirstZnode [zk: localhost:2181(CONNECTED) 11] get /FirstZnode Node does not exist: /FirstZnode
刪除(刪除/路徑)命令相似remove命令,但它僅適用於無子znode的znode。