ZooKeeper 是一個分佈式的,開放源碼的分佈式應用程序協同服務。ZooKeeper 的設計目標是將那些複雜且容易出錯的分佈式一致性服務封裝起來,構成一個高效可靠的原語集,並以一系列簡單易用的接口提供給用戶使用。html
ZooKeeper 最先起源於雅虎研究院的一個研究小組。在當時,研究人員發現,在雅虎內部不少大型系統基本都須要依賴一個相似的系統來進行分佈式協同,可是這些系統每每都存在分佈式單點問題。java
因此,雅虎的開發人員就開發了一個通用的無單點問題的分佈式協調框架,這就是 ZooKeeper。ZooKeeper 以後在開源界被大量使用,下面列出了 3 個著名開源項目是如何使用 ZooKeeper:node
不少分佈式協調服務均可以用 ZooKeeper 來作,其中典型應用場景以下:數據庫
ZooKeeper 適用於存儲和協同相關的關鍵數據,不適合用於大數據量存儲。若是要存 KV 或者大量的業務數據,仍是要用數據庫或者其餘 NoSql 來作。apache
爲何 ZooKeeper 不適合大數據量存儲呢?主要有如下兩個緣由:vim
要使用 ZooKeeper 服務,首先咱們的應用要引入 ZooKeeper 的客戶端庫,而後咱們客戶端庫和 ZooKeeper 集羣來進行網絡通訊來使用 ZooKeeper 的服務,本質上是 Client-Server 的架構,咱們的應用做爲一個客戶端來調用 ZooKeeper Server 端的服務。服務器
ZooKeeper 的數據模型是層次模型。層次模型常見於文件系統。層次模型和 key-value 模型是兩種主流的數據模型。ZooKeeper 使用文件系統模型主要基於如下兩點考慮:網絡
ZooKeeper 的層次模型稱做 data tree。Data tree 的每一個節點叫作 znode。不一樣於文件系統,每一個節點均可以保存數據。每一個節點都有一個版本(version),版本從 0 開始計數。session
如上圖所示的 data tree 中有兩個子樹,一個用於應用 1(/app1)和另外一個用於應用 2(/app2)。架構
應用 1 的子樹實現了一個簡單的組成員協議:每一個客戶端進程 pi 建立一個 znode p_i 在 /app1 下,只要 /app1/p_i 存在就表明進程 pi 在正常運行。
ZooKeeper 對外提供一個用來訪問 data tree的簡化文件系統 API:
一個 znode 能夠是持久性的,也能夠是臨時性的,znode 節點也能夠是順序性的。每個順序性的 znode 關聯一個惟一的單調遞增整數,所以 ZooKeeper 主要有如下 4 種 znode:
到 https://archive.apache.org/dist/zookeeper/stable/ 下載 ZooKeeper,目前的最新版是 3.5.6。
把 apache-zookeeper-3.5.6-bin.tar.gz 解壓到一個本地目錄 (目錄名最好不要包含空格和中文)。我使用 /usr/local 目錄。
tar -zxvf apache-zookeeper-3.5.6-bin.tar.gz
把 conf 目錄下的 zoo_sample.cfg 重命名爲 zoo.cfg,而後修改配置。
# 心跳檢查的時間 2秒 tickTime=2000 # 初始化時 鏈接到服務器端的間隔次數,總時間10*2=20秒 initLimit=10 # ZK Leader 和follower 之間通信的次數,總時間5*2=10秒 syncLimit=5 # 存儲內存中數據快照的位置,若是不設置參數,更新事務日誌將被存儲到默認位置。 dataDir=/data/zookeeper # ZK 服務器端的監聽端口 clientPort=2181
配置如下環境變量 vim /etc/profile
:
export ZOOKEEPER_HOME=/usr/local/apache-zookeeper-3.5.6-bin export PATH=$PATH:$ZOOKEEPER_HOME/bin:$ZOOKEEPER_HOME/conf
再安裝配置完成後,就能夠啓動 Zookeeper,使用 zkServer.sh start 啓動 ZooKeeper 服務:
[root@wupx apache-zookeeper-3.5.6-bin]# zkServer.sh start /usr/bin/java ZooKeeper JMX enabled by default Using config: /usr/local/apache-zookeeper-3.5.6-bin/bin/../conf/zoo.cfg Starting zookeeper ... STARTED
檢查 ZooKeeper 日誌是否有出錯信息:
[root@wupx apache-zookeeper-3.5.6-bin]# cd logs/ [root@wupx logs]# grep -E -i "((exception)|(error))" *
由於返回沒有結果,說明沒有錯誤信息。
檢查 ZooKeeper 數據文件,這裏存放的 ZooKeeper 的事務日誌文件和快照日誌文件。
[root@wupx zookeeper]# cd /data/zookeeper/ [root@wupx zookeeper]# tree . ├── version-2 │ └── snapshot.0 └── zookeeper_server.pid 1 directory, 2 files
由於如今尚未運行任何 ZooKeeper 命令,因此尚未事務日誌文件。
最後會檢查 ZooKeeper 是否在 2181 端口上監聽。
netstat -an | ag 2181
執行後,咱們能夠看到 ZooKeeper 已經在 2181 這個端口上監聽了。
下面咱們演示下如何使用 zkCli:
在執行 zkCli.sh
命令後,會出現不少消息,這些消息證實咱們的 zkCli 和 ZooKeeper 的節點創建了有效鏈接。
2019-12-22 10:38:36,684 [myid:localhost:2181] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@959] - Socket connection established, initiating session, client: /127.0.0.1:54038, server: localhost/127.0.0.1:2181
使用 ls -R /
能夠遞歸查找 ZooKeeper 的 znode 節點,使用 create /znode_name
能夠建立 znode 節點,具體演示以下:
# 使用 ls -R 能夠遞歸查找 ZooKeeper 的 znode 節點 [zk: localhost:2181(CONNECTED) 0] ls -R / / /zookeeper /zookeeper/config /zookeeper/quota # 建立 znode /app1 [zk: localhost:2181(CONNECTED) 1] create /app1 Created /app1 [zk: localhost:2181(CONNECTED) 2] create /app2 Created /app2 [zk: localhost:2181(CONNECTED) 3] create /app1/p_1 1 Created /app1/p_1 [zk: localhost:2181(CONNECTED) 4] create /app1/p_2 2 Created /app1/p_2 [zk: localhost:2181(CONNECTED) 5] create /app1/p_3 3 Created /app1/p_3 [zk: localhost:2181(CONNECTED) 6] ls -R / / /app1 /app2 /zookeeper /app1/p_1 /app1/p_2 /app1/p_3 /zookeeper/config /zookeeper/quota
分佈式鎖要求若是鎖的持有者宕了,鎖能夠被釋放。ZooKeeper 的 ephemeral 節點剛好具有這樣的特性。
接下來咱們來演示下,須要在兩個終端上分別啓動 zkCli,
在終端 1 上:
執行 zkCli.sh
,再執行 create -e /lock
命令,來創建臨時 znode,加鎖的操做其實就是創建 znode 的過程,此時第一個客戶端加鎖成功。
接下來嘗試在第二個客戶端加鎖,在終端 2 上:
執行 zkCli.sh
,再執行 create -e /lock
命令,會發現提示 Node already exists: /lock
,提示 znode 已存在,znode 創建失敗,所以加鎖失敗,這時候咱們來監控這個 znode,使用 stat -w /lock
來等待鎖被釋放。
這個時候咱們退出第一個客戶端,在終端 1 上執行 quit
命令,會在客戶端 2 上收到一條 WATCHER 信息,具體以下:
WATCHER:: WatchedEvent state:SyncConnected type:NodeDeleted path:/lock
再收到這個事件後再次在客戶端 2 上執行加鎖,執行 create -e /lock
,會顯示建立 znode 成功,即加鎖成功。
這篇文章主要介紹了 ZooKeeper 的安裝配置,ZooKeeper 的基本概念和 zkCli 的使用,並用 zkCli 來實現一個鎖,爲後面更加深刻的學習打好基礎。
參考
https://zookeeper.apache.org/doc/current/zookeeperOver.html
https://zookeeper.apache.org/doc/current/zookeeperStarted.html
《從Paxos到Zookeeper:分佈式一致性原理與實踐》