Apache ZooKeeper
zk入門指南
閱讀本文檔能使您快速瞭解並使用ZooKeeper。 主要內容包含:
- 瞭解ZooKeeper的相關的概念
- 下載安裝ZooKeeper服務
- Zookeeper的配置、啓動與客戶端連接
- 瞭解ZooKeeper的一些簡單命令
什麼是ZooKeeper?
ZooKeeper翻譯成中文的意思是動物管理員
,它是一個分佈式服務框架,用於維護配置信息,提供統一命名,分佈式狀態同步,集羣管理等服務。
基本概念
爲了更快的掌握zookeeper,我們首先需要了解zookeeper中的一些基本概念,例如集羣角色(leader、follower、observer)
,會話(session)
,數據節點(ZNode)
,狀態信息
,事務操作
,事件監聽器(watcher)
,ACL
集羣角色
- leader:負責進行投票的發起和決議,更新系統狀態
- follower:接收客戶端請求,參與投票
- observer:接收客戶端請求,將寫請求轉發給leader,不參加投票過程,只同步leader的狀態,observer的目的是爲了擴展系統,提高讀取速度
Session
session是指客戶端和zookeeper服務器之間的一個TCP長連接。從第一次建立連接開始,客戶端session會話生命週期就開始了。client可以通過心跳監測和服務器保持有效的會話,同時也可以通過該連接接收服務器的watch事件通知。
ZNode
zookeeper中的ZNode稱爲數據節點。是指數據模型中的數據單元。ZNode是一個樹,由斜槓(/)分隔路徑,例如 :/hbash/master/
其中,hbash
和 master
分別都是一個ZNode,在自己的ZNode中保存自己的數據。可以簡單的將ZNode理解爲Unix的文件系統。
- 3.1 節點類型
持久節點:必須主動刪除纔會失效
臨時節點:會話失效時就會失效。
- 3.2 版本
zookeeper會爲每個ZNode維護一個Stat的數據結構,在該結構中記錄了ZNode的三個版本
- version - 當前版本
- cversion - 當前ZNode的子節點的版本
- aversion - 當前ZNode的ACL版本 (ACL : 訪問控制列表)
事務
在zookeeper中,把改變zookeeper服務器狀態的操作稱爲事務操作。一般包括ZNode節點的創建與刪除、數據內容的更新、客戶端session
的建立與失效等操作。每一個事務請求,zk都會爲其分配一個全局的事務ID,用ZXID表示,通常是一個64位的數字(它高32位是epoch用來標識 leader關係是否改變,每次一個leader被選出來,它都會有一個新的epoch,標識當前屬於那個leader的統治時期。低32位用於遞增計數。
)。每一個ZXID對應的一次更新操作,從這些ZXID中可以間接識別出zk處理這些事務操作的全局順序一致性。
Watcher
watcher即事件監聽器,是zk中的一個重要的分佈式協調的特性。zk允許用戶在指定節點註冊一些watcher,並在特定事件觸發時,zk會將通知到指定客戶端上。
ACL
ACL全稱爲access control lists ,是zk的一種權限控制策略。zk定義瞭如下5中權限:
- create : 創建子節點的權限
- read:獲取節點數據和子節點列表
- write:更新節點數據
- delete:刪除子節點
- admain:設置節點ACL權限
下載
因爲zookeeper依賴JDK,所以需要先下載安裝JDK。 沒有安裝JDK的同學移步教程---->>> 一分鐘搞定JDK的安裝與配置
JDK8:JDK8的下載地址
Apache最新穩定版:zookeeper官網鏡像地址
TIPS:選擇版本下載一定要注意選擇帶bin
的安裝包,否則下載錯文件可能導致zkServer.sh start
無法啓動 。
或點擊直接下載:apache-zookeeper-3.6.2-bin.tar.gz
安裝
下載好apache-zookeeper-3.6.2.tar.gz
後,在根目錄創建servers
目錄,我們稍後把zk安裝到這裏方便管理。
- 解壓
- 執行命令,
tar -xvzf
解壓,加-C ~/servers
的作用是指定目錄
tar -xvzf apache-zookeeper-3.6.2.tar.gz -C ~/servers/ ```
2. 爲zk建立軟連接
* 進入servers目錄
```bash
[lb@centos-linux servers]$ ln -s apache-zookeeper-3.6.2 zookeeper
[lb@centos-linux servers]$ ls
apache-zookeeper-3.6.2 zookeeper
- 到此爲止,我們的zk就安裝成功了。看一下目錄結構
[lb@centos-linux zookeeper]$ pwd
/home/lb/servers/zookeeper
[lb@centos-linux zookeeper]$ ls
bin excludeFindBugsFilter.xml pom.xml zookeeper-compatibility-tests zookeeper-recipes
checkstyle-simple.xml Jenkinsfile README.md zookeeper-contrib zookeeper-server
checkstyle-strict.xml Jenkinsfile-PreCommit README_packaging.md zookeeper-docs
checkstyleSuppressions.xml LICENSE.txt zk-merge-pr.py zookeeper-it
conf NOTICE.txt zookeeper-assembly zookeeper-jute
dev owaspSuppressions.xml zookeeper-client zookeeper-metrics-providers
[lb@centos-linux zookeeper]$
配置
- 進入/zookeeper/conf/目錄,拷貝
zoo_sample.cfg
文件,拷貝爲一個新的配置:zoo.cfg
cp zoo_sample.cfg zoo.cfg
- 編輯
zoo.cfg
,修改dataDir配置,wq保存並退出
dataDir=/home/lb/servers/zookeeper/data
- 返回
zookeeper
目錄,新建data
文件夾
-p
, --parents 需要時創建目標目錄的上層目錄,但即使這些目錄已存在也不當作錯誤處理-v
, --verbose 每次創建新目錄都顯示信息
mkdir -p -v data
- 配zk的環境變量
- 編輯bash_profile ,新增如下配置:
export ZOOKEEPER_HOME=/home/lb/servers/zookeeper
PATH=$ZOOKEEPER_HOME/bin:$PATH
- 最終的配置如下:
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
export JAVA_HOME=/home/lb/package/java
export ZOOKEEPER_HOME=/home/lb/servers/zookeeper
PATH=$PATH:$HOME/.local/bin:$HOME/bin
PATH=$JAVA_HOME/bin:$PATH
PATH=$ZOOKEEPER_HOME/bin:$PATH
export PATH
- 使配置生效
source ~/.bash_profile
開始使用
啓動zkServer
- 執行命令
zkServer.sh start
# 查看zkServer有哪些命令
[lb@centos-linux conf]$ zkServer.sh
ZooKeeper JMX enabled by default
Using config: /home/lb/servers/zookeeper/bin/../conf/zoo.cfg
Usage: /home/lb/servers/zookeeper/bin/zkServer.sh [--config <conf-dir>] {start|start-foreground|stop|version|restart|status|print-cmd}
# 啓動zk服務
[lb@centos-linux conf]$ zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /home/lb/servers/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[lb@centos-linux conf]$
# 查看zk服務狀態
[lb@centos-linux conf]$ zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /home/lb/servers/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost. Client SSL: false.
Mode: standalone # 單機版
[lb@centos-linux conf]$
客戶端連接zkServer
- 直接執行zkCli.sh
zkCli.sh
Connecting to localhost:2181
2020-12-18 09:59:43,848 [myid:] - INFO [main:Environment@98] - Client environment:zookeeper.version=3.6.2--803c7f1a12f85978cb049af5e4ef23bd8b688715, built on 09/04/2020 12:44 GMT
2020-12-18 09:59:43,850 [myid:] - INFO [main:Environment@98] - Client environment:host.name=centos-linux.shared
2020-12-18 09:59:43,850 [myid:] - INFO [main:Environment@98] - Client environment:java.version=1.8.0_271
2020-12-18 09:59:43,851 [myid:] - INFO [main:Environment@98] - Client environment:java.vendor=Oracle Corporation
2020-12-18 09:59:43,851 [myid:] - INFO [main:Environment@98] - Client environment:java.home=/home/lb/package/jdk1.8.0_271/jre
2020-12-18 09:59:43,851 [myid:] - INFO [main:Environment@98] - Client environment:java.class.path=/home/lb/servers/zookeeper/bin/../zookeeper-server/target/classes:/home/lb/servers/zookeeper/bin/../build/classes:/home/lb/servers/zookeeper/bin/../zookeeper-server/target/lib/*.jar:/home/lb/servers/zookeeper/bin/../build/lib/*.jar:/home/lb/servers/zookeeper/bin/../lib/zookeeper-prometheus-metrics-3.6.2.jar:/home/lb/servers/zookeeper/bin/../lib/zookeeper-jute-3.6.2.jar:/home/lb/servers/zookeeper/bin/../lib/zookeeper-3.6.2.jar:/home/lb/servers/zookeeper/bin/../lib/snappy-java-1.1.7.jar:/home/lb/servers/zookeeper/bin/../lib/slf4j-log4j12-1.7.25.jar:/home/lb/servers/zookeeper/bin/../lib/slf4j-api-1.7.25.jar:/home/lb/servers/zookeeper/bin/../lib/simpleclient_servlet-0.6.0.jar:/home/lb/servers/zookeeper/bin/../lib/simpleclient_hotspot-0.6.0.jar:/home/lb/servers/zookeeper/bin/../lib/simpleclient_common-0.6.0.jar:/home/lb/servers/zookeeper/bin/../lib/simpleclient-0.6.0.jar:/home/lb/servers/zookeeper/bin/../lib/netty-transport-native-unix-common-4.1.50.Final.jar:/home/lb/servers/zookeeper/bin/../lib/netty-transport-native-epoll-4.1.50.Final.jar:/home/lb/servers/zookeeper/bin/../lib/netty-transport-4.1.50.Final.jar:/home/lb/servers/zookeeper/bin/../lib/netty-resolver-4.1.50.Final.jar:/home/lb/servers/zookeeper/bin/../lib/netty-handler-4.1.50.Final.jar:/home/lb/servers/zookeeper/bin/../lib/netty-common-4.1.50.Final.jar:/home/lb/servers/zookeeper/bin/../lib/netty-codec-4.1.50.Final.jar:/home/lb/servers/zookeeper/bin/../lib/netty-buffer-4.1.50.Final.jar:/home/lb/servers/zookeeper/bin/../lib/metrics-core-3.2.5.jar:/home/lb/servers/zookeeper/bin/../lib/log4j-1.2.17.jar:/home/lb/servers/zookeeper/bin/../lib/json-simple-1.1.1.jar:/home/lb/servers/zookeeper/bin/../lib/jline-2.14.6.jar:/home/lb/servers/zookeeper/bin/../lib/jetty-util-9.4.24.v20191120.jar:/home/lb/servers/zookeeper/bin/../lib/jetty-servlet-9.4.24.v20191120.jar:/home/lb/servers/zookeeper/bin/../lib/jetty-server-9.4.24.v20191120.jar:/home/lb/servers/zookeeper/bin/../lib/jetty-security-9.4.24.v20191120.jar:/home/lb/servers/zookeeper/bin/../lib/jetty-io-9.4.24.v20191120.jar:/home/lb/servers/zookeeper/bin/../lib/jetty-http-9.4.24.v20191120.jar:/home/lb/servers/zookeeper/bin/../lib/javax.servlet-api-3.1.0.jar:/home/lb/servers/zookeeper/bin/../lib/jackson-databind-2.10.3.jar:/home/lb/servers/zookeeper/bin/../lib/jackson-core-2.10.3.jar:/home/lb/servers/zookeeper/bin/../lib/jackson-annotations-2.10.3.jar:/home/lb/servers/zookeeper/bin/../lib/commons-lang-2.6.jar:/home/lb/servers/zookeeper/bin/../lib/commons-cli-1.2.jar:/home/lb/servers/zookeeper/bin/../lib/audience-annotations-0.5.0.jar:/home/lb/servers/zookeeper/bin/../zookeeper-*.jar:/home/lb/servers/zookeeper/bin/../zookeeper-server/src/main/resources/lib/*.jar:/home/lb/servers/zookeeper/bin/../conf:
2020-12-18 09:59:43,851 [myid:] - INFO [main:Environment@98] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2020-12-18 09:59:43,852 [myid:] - INFO [main:Environment@98] - Client environment:java.io.tmpdir=/tmp
2020-12-18 09:59:43,852 [myid:] - INFO [main:Environment@98] - Client environment:java.compiler=<NA>
2020-12-18 09:59:43,852 [myid:] - INFO [main:Environment@98] - Client environment:os.name=Linux
2020-12-18 09:59:43,852 [myid:] - INFO [main:Environment@98] - Client environment:os.arch=amd64
2020-12-18 09:59:43,852 [myid:] - INFO [main:Environment@98] - Client environment:os.version=3.10.0-327.el7.x86_64
2020-12-18 09:59:43,852 [myid:] - INFO [main:Environment@98] - Client environment:user.name=lb
2020-12-18 09:59:43,852 [myid:] - INFO [main:Environment@98] - Client environment:user.home=/home/lb
2020-12-18 09:59:43,852 [myid:] - INFO [main:Environment@98] - Client environment:user.dir=/home/lb/servers/apache-zookeeper-3.6.2-bin/conf
2020-12-18 09:59:43,852 [myid:] - INFO [main:Environment@98] - Client environment:os.memory.free=23MB
2020-12-18 09:59:43,853 [myid:] - INFO [main:Environment@98] - Client environment:os.memory.max=228MB
2020-12-18 09:59:43,853 [myid:] - INFO [main:Environment@98] - Client environment:os.memory.total=29MB
2020-12-18 09:59:43,857 [myid:] - INFO [main:ZooKeeper@1006] - Initiating client connection, connectString=localhost:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@1175e2db
2020-12-18 09:59:43,863 [myid:] - INFO [main:X509Util@77] - Setting -D jdk.tls.rejectClientInitiatedRenegotiation=true to disable client-initiated TLS renegotiation
2020-12-18 09:59:43,872 [myid:] - INFO [main:ClientCnxnSocket@239] - jute.maxbuffer value is 1048575 Bytes
2020-12-18 09:59:43,881 [myid:] - INFO [main:ClientCnxn@1716] - zookeeper.request.timeout value is 0. feature enabled=false
Welcome to ZooKeeper!
2020-12-18 09:59:43,892 [myid:localhost:2181] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1167] - Opening socket connection to server localhost/127.0.0.1:2181.
2020-12-18 09:59:43,892 [myid:localhost:2181] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1169] - SASL config status: Will not attempt to authenticate using SASL (unknown error)
2020-12-18 09:59:43,896 [myid:localhost:2181] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@999] - Socket connection established, initiating session, client: /127.0.0.1:39308, server: localhost/127.0.0.1:2181
JLine support is enabled
2020-12-18 09:59:43,923 [myid:localhost:2181] - INFO [main-SendThread(localhost:2181):ClientCnxn$SendThread@1433] - Session establishment complete on server localhost/127.0.0.1:2181, session id = 0x10000fc83a10000, negotiated timeout = 30000
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
[zk: localhost:2181(CONNECTED) 0]
[zk: localhost:2181(CONNECTED) 0]
說明連接成功了!
一些簡單命令
查看節點目錄
命令:ls <節點名稱>
- 查看根目錄ZNode
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper]
- 查看
zookeeper
節點下有哪些節點
[zk: localhost:2181(CONNECTED) 1] ls /zookeeper
[config, quota]
- 查看
quota
節點的子節點,結果爲[ ]
說明沒有子節點
[zk: localhost:2181(CONNECTED) 8] ls /zookeeper/quota
[]
查看節點屬性
命令:get -s <節點名稱>
- 查看
zookeeper
節點有哪些屬性
[zk: localhost:2181(CONNECTED) 17] get -s /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 = -2
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 2
- 查看
quota
數據節點有哪些屬性
[zk: localhost:2181(CONNECTED) 21] get -s /zookeeper/quota
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 = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 0
添加數據節點
命令:create <數據節點路徑及名稱> <數據節點內容>
- 在根目錄添加一個
home
節點,節點內容爲123
[zk: localhost:2181(CONNECTED) 22] create /home 123
Created /home
#查看home節點屬性
[zk: localhost:2181(CONNECTED) 23] get -s /home
123 #節點內容
cZxid = 0x2
ctime = Fri Dec 18 10:23:11 CST 2020
mZxid = 0x2
mtime = Fri Dec 18 10:23:11 CST 2020
pZxid = 0x2
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0
修改數據節點
命令:set <數據節點名稱> <數據內容>
- 修改數據節點
home
的值爲123456
[zk: localhost:2181(CONNECTED) 24] set /home 123456
[zk: localhost:2181(CONNECTED) 25] get -s /home
123456
cZxid = 0x2
ctime = Fri Dec 18 10:23:11 CST 2020
mZxid = 0x3 #mZxid+1
mtime = Fri Dec 18 10:25:46 CST 2020 # 時間更新
pZxid = 0x2
cversion = 0
dataVersion = 1 #版本+1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6 #數據長度更新
numChildren = 0
刪除數據節點
語法:delete <數據節點路徑>
tips:只有沒有子節點的節點才允許刪除,例如如下案例:
- home節點下創建了一個n1節點
[zk: localhost:2181(CONNECTED) 36] create /home/n1 ''
Created /home/n1
[zk: localhost:2181(CONNECTED) 38] ls /home
[n1]
- 刪除home節點,會提示
Node not empty: /home
[zk: localhost:2181(CONNECTED) 40] delete /home
Node not empty: /home
- 刪除n1節點,沒有問題,刪除成功
[zk: localhost:2181(CONNECTED) 41] delete /home/n1
[zk: localhost:2181(CONNECTED) 42] ls /home
[]
恭喜你!關於zookeeper的簡單入門就到到此爲止啦!
如果想了解更多關於ZooKeeper的高階知識,請閱讀: