目錄javascript
zookeeper 是軟件世界裏的管理者,被用來 提供分佈式環境的協調服務。zookeeper 是 yahoo 公司使用 java 語言開發的,是 Hadoop 項目中的子項目,基於 Google 的 Chubby 的開源實現,在 Hadoop,Hbase,Kafka 等技術中充當核心組件的角色。java
它的設計目標就是 將那些複雜而且容易出錯的分佈式一致性服務加以封裝,構成高效且可靠的服務,併爲用戶提供一系列簡單易用的接口。node
Zookeeper 是一個經典的 分佈式數據一致性 解決方案,分佈式應用程序能夠基於它實現linux
zookeeper 通常都以 集羣的方式 對外提供服務,一個集羣包含多個節點,每一個節點都對應一臺 Zookeeper 服務器,全部的節點共同對外提供服務。具體包括如下五大特性:shell
Zookeeper 內部擁有樹狀的內存模型,與文件系統很是相似。apache
樹狀模型圖以下所示npm
ZNode 包含 4 類節點服務器
Zookeeper 設計了一個輕量級的協議 Zab (ZooKeeper Atomic Broadcast, Zookeeper 廣播協議)。Zab 協議分爲兩個階段:session
Leader Election 領導選舉架構
Zookeeper 集羣啓動時,會選出一臺節點爲 Leader,而其餘節點均爲 Follower。當 Leader 出現故障時,會自動選舉出新的 Leader 節點,並讓全部節點恢復到一個正常的狀態。選舉結束後,會進入 原子廣播階段。
Atomic Broadcase 原子廣播
該階段會同步 Leader 節點與 Follower 節點之間的數據,確保 Leader 與 Follower 節點具備相同的狀態。全部的寫操做都會發送到 Leader 節點,並經過廣播的方式同步到 Follower 節點。
一個 Zookeeper 集羣一般由一組節點組成,通常狀況下 3 ~ 5 個就能夠組成可用的 Zookeeper 集羣。
每一個節點都會在內存中維護當前的服務器狀態,並在每一個節點之間都會保持通訊,目的就是告訴其餘節點「本身還活着」。咱們通常會提供奇數個節點比較節省資源。此外, Zookeeper 客戶端能夠選擇集羣中任意一個節點來創建鏈接,而一旦客戶端與某個節點之間斷開聯繫,客戶端會自動鏈接到集羣的其餘節點。
zookeeper 官方地址:http://zookeeper.apache.org/
zookeeper 使用 java 語言開發,使用前須要先安裝 jdk。下文是在 linux 環境下運行 zookeeper 的指導。
Zookeeper 默認提供了一份名爲 zoo_sample.cfg
的示例配置文件,須要複製一下,並將其重命名爲 zoo.cfg
。配置文件的重要配置項以下
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/tmp/zookeeper clientPort=2181
詳細解釋下以上配置項
tickTime
滴答時間,用於配置 Zookeeper 中最小時間單元的長度。單位爲 ms。默認值是 3000 ms。initLimit
用於配置 Leader 節點等待 Follower 節點啓動並完成數據同步的時間, 默認值是 10 ,也就是 10 * tickTimesyncLimit
用來配置 Leader 節點與 Follower 節點之間心跳檢測的最大延時時間,默認值是 5,也就是 5 * tickTimedataDir
用來配置 Zookeeper 服務器存儲快照文件的目錄,不建議將其指定到 /tmp 目錄下,由於該目錄下的全部文件可能被自動刪除。在 Zookeeper 環境中,將生成一個名爲 myid 的文件,用來存放 zk 集羣節點的 ID。clientPort
用於配置當前 zk 服務器對外暴露的接口啓動 Zookeeper 服務器很是簡單,只需執行 Zookeeper 提供的腳本程序便可。
bin/zkServer.sh start
執行上面腳本,默認會在後臺啓動 Zookeeper 服務器。
zkServer.sh
能夠傳入如下參數
bin/zkServer.sh status
還可使用 telnet 命令來驗證 ZooKeeper 服務是否有效
telnet 127.0.0.1 2181
zookeeper 當前處於 standard alone 模式下,通常狀況下咱們使用單機模式做爲開發環境,而使用集羣模式做爲生產環境。
在本地搭建一個僞集羣模式的 Zookeeper 集羣環境(3 個節點)
配置以下
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/usr/local/app-data/zookeeper/data dataLogDir=/usr/local/zookeeper-3.4.6/logs clientPort=2181 server.0=127.0.0.1:2888:3888 server.1=127.0.0.1:2889:3889 server.2=127.0.0.1:2890:3890
與單機模式的區別就在於添加了一組 server 配置,表示集羣中包含的三個節點,須要注意的是 server 配置須要知足必定的格式:
server.<id>=<ip>:<port1>:<port2>
與單機模式的啓動方法相同,只需一次啓動全部的 ZooKeeper 節點便可啓動整個集羣
和 standard alone 模式同樣,也能夠經過 zkServer.sh 腳本與 telnet 命令來查看每一個節點的狀態,此時會看到 Mode:leader
或者 Mode:follower
的信息,表示該節點是 Leader 仍是 Follower。
ZooKeeper 提供了一系列腳本程序,所有存放在 bin 目錄下,如
鏈接 ZooKeeper 只須要執行如下腳本:
bin/zkCli.sh
若是想要鏈接遠程的 ZooKeeper, 則在 zkCli.sh 腳本中添加 -server 選項
bin/zkCli.sh -server <ip>:<port>
鏈接成功後,就能夠輸入相關的命令來操做 zookeeper 了。當輸入 help 命令後,將輸出 zookeeper 相關客戶端命令的使用幫助。
ZooKeeper -server host:port cmd args stat path [watch] set path data [version] ls path [watch] delquota [-n|-b] path ls2 path [watch] setAcl path acl setquota -n|-b val path history redo cmdno printwatches on|off delete path [version] sync path listquota path rmr path get path [watch] create [-s] [-e] path data acl addauth scheme auth quit getAcl path close connect host:port
命令格式以下
ls path [watch]
ls 命令中可設置一個 watch
參數,用於指定客戶端監視器,在 zooKeeper 中被稱爲 Watcher, Watcher 用於監控節點的狀態變化,默認狀況下可不帶有任何 Watcher。
[zk: localhost:2181(CONNECTED) 0] ls / [zookeeper]
默認狀況下,根目錄中有一個名爲 zookeeper 的子節點,它做爲 Zookeeper 的保留節點,咱們通常不使用它。
此外,還可使用 ls2
命令以更加詳細的方式列出節點名稱及其相關屬性,命令格式以下
ls2 path [watch]
ls2 命令會輸出當前節點的基本信息
[zk: localhost:2181(CONNECTED) 2] ls2 / [zookeeper] cZxid = 0x0 ctime = Thu Jan 01 08:00:00 CST 1970 mZxid = 0x0 mtime = Thu Jan 01 08:00:00 CST 1970 pZxid = 0x0 cversion = -1 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 0 numChildren = 1
在輸出信息中包含了大量的統計屬性:
cZxid
表示建立節點時的事務 ID (每一個客戶端請求都會造成一個事務)ctime
表示建立節點的時間mZxid
表示最後一次修改節點時的事務 IDmtime
表示最後一次修改節點的時間pZxid
表示最後一次修改父節點時的事務 IDcversion
子節點的版本號dataVersion
節點包含數據的版本號aclVersion
表示節點的 ACL 權限版本號ephemeralOwner
臨時節點的會話 IDdataLength
表示節點包含數據內容的長度numChildren
當前節點的子節點數[zk: localhost:2181(CONNECTED) 8] stat /foo Node does not exist: /foo
使用 create 命令建立節點,命令格式以下
create [-s] [-e] path data acl
其中
-s
用於指定該節點是否爲順序節點,即 Sequential 節點
-e
選項:用於指定該節點是否爲臨時節點,即 Ephemeral 節點
acl
用於權限控制, Zookeeper 內部提供了一個強大的 ACL 訪問控制列表,默認狀況下不作任何權限控制
[zk: localhost:2181(CONNECTED) 13] create -e /foo hello Created /foo
使用 get 命令獲取節點數據,命令格式以下
get path [watch]
能夠經過如下命令獲取 /foo 節點包含的數據
[zk: localhost:2181(CONNECTED) 14] get /foo hello cZxid = 0xa ctime = Wed Jan 02 15:27:44 CST 2019 mZxid = 0xa mtime = Wed Jan 02 15:27:44 CST 2019 pZxid = 0xa cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x1680d4a324f0002 dataLength = 5 numChildren = 0
使用 set 命令更新節點數據,命令格式以下
set path data [version]
在更新節點數據時,可指定 version 參數,表示節點包含數據的版本號。若是不指定 version 參數,則表示更新節點數據的最新版本。
使用 delete 命令刪除節點,命令格式以下
delete path [version]
當節點沒有任何子節點時,才能刪除成功,不然將給出 "node not empty" 的提示,但能夠經過如下命令一次刪除該節點及其全部的子節點。
rmr path
Node.js 鏈接 Zookeeper 中比較好用的客戶端是 node-zookeeper-client
。
首先經過 NPM 來安裝這個模塊。
npm install node-zookeeper-client
先用一段代碼來展現鏈接 Zookeeper, 後面再基於該代碼,將 nodejs 針對 zookeeper 客戶端的操做執行一遍。
var zookeeper = require('node-zookeeper-client') var CONNECTION_STRING = 'localhost:2181' var OPTIONS = { sessionTimeout: 5000 } var zk = zookeeper.createClient(CONNECTION_STRING, OPTIONS) zk.on('connected', function() { console.log(zk); zk.close(); }); zk.connect();
若是 zk 能夠正常輸出,說明可成功鏈接 Zookeeper 服務器並創建了正常的會話, 下面全部的操做都在該會話中進行。Node.js 客戶端僅提供了異步方式,咱們不能經過同步方式來調用。
node-zookeeper-client 的官方文檔地址爲: https://www.npmjs.com/package/node-zookeeper-client
可執行的常見操做包括: