ZooKeeper作為頂級(jí)分布式開源項(xiàng)目,應(yīng)用非常廣泛,Dubbo和Kafka這些知名的開源項(xiàng)目都在使用。之前只是聽說(shuō)過(guò)它,并沒有仔細(xì)研究過(guò)。今天帶大家來(lái)學(xué)習(xí)下ZooKeeper,主要從ZooKeeper的安裝、可視化工具、應(yīng)用三方面來(lái)介紹,希望對(duì)大家有所幫助!
簡(jiǎn)介
ZooKeeper是一款分布式協(xié)調(diào)框架,它可以為分布式系統(tǒng)提供一致性服務(wù)。ZooKeeper最初由Yahoo開發(fā),后來(lái)捐獻(xiàn)給了Apache基金會(huì),現(xiàn)已成功Apache的頂級(jí)項(xiàng)目,目前在Github上有9.5k+Star。
分布式協(xié)調(diào)
要理解ZooKeeper我們首先需要了解下什么是分布式協(xié)調(diào)?這里拿Spring Cloud中注冊(cè)中心的例子來(lái)說(shuō)吧。
微服務(wù)(分布式)系統(tǒng)中有很多服務(wù),相同的服務(wù)又有多個(gè)實(shí)例,我們?cè)趹?yīng)用中可以通過(guò)服務(wù)名來(lái)負(fù)載均衡地調(diào)用服務(wù),而這些服務(wù)有可能會(huì)掛掉,也有可能會(huì)有新的實(shí)例加入。此時(shí)我們就需要一個(gè)東西來(lái)做協(xié)調(diào),保存好服務(wù)名稱和可用實(shí)例調(diào)用IP的對(duì)應(yīng)關(guān)系,此時(shí)注冊(cè)中心就是一個(gè)分布式協(xié)調(diào)者的角色,而ZooKeeper就可以用來(lái)充當(dāng)這個(gè)協(xié)調(diào)者。
安裝
ZooKeeper的安裝無(wú)論是Windows還是Linux都是很方便的,我們先來(lái)學(xué)習(xí)下它的安裝。
Windows安裝
- 首先下載ZooKeeper安裝包,下載地址:https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz
image.png
- 解壓到指定目錄,解壓完成后目錄結(jié)構(gòu)如下;

- 在
conf目錄下創(chuàng)建配置文件zoo.cfg,內(nèi)容如下;
# 設(shè)置心跳時(shí)間,單位毫秒
tickTime=2000
# 存儲(chǔ)內(nèi)存數(shù)據(jù)庫(kù)快照的文件夾
dataDir=I:/developer/env/apache-zookeeper-3.7.0-bin/data
# 監(jiān)聽客戶端連接的端口
clientPort=2181
- 進(jìn)入
bin目錄,啟動(dòng)ZooKeeper服務(wù);
zkServer.cmd
-
服務(wù)啟動(dòng)成功后,控制臺(tái)會(huì)輸出如下信息。image.png
·Linux安裝
- 使用Docker安裝ZooKeeper無(wú)疑是最方便的,首先我們下載它的Docker鏡像;
docker pull zookeeper:3.7.0
- 創(chuàng)建好ZooKeeper的配置文件目錄,并切換到該目錄創(chuàng)建配置文件
zoo.cfg;
mkdir /mydata/zookeeper/conf/ -p
cd /mydata/zookeeper/conf/
touch zoo.cfg
- 配置文件
zoo.cfg內(nèi)容如下,直接使用VIM編輯即可;
# 設(shè)置心跳時(shí)間,單位毫秒
tickTime=2000
# 存儲(chǔ)內(nèi)存數(shù)據(jù)庫(kù)快照的文件夾
dataDir=/tmp/zookeeper
# 監(jiān)聽客戶端連接的端口
clientPort=2181
- 運(yùn)行ZooKeeper容器。
docker run -p 2181:2181 --name zookeeper \
-v /mydata/zookeeper/conf/zoo.cfg:/conf/zoo.cfg \
-d zookeeper:3.7.0
命令行操作
接下來(lái)我們用命令行來(lái)操作下ZooKeeper,熟悉下ZooKeeper的使用。
首先使用zkCli命令行工具連接到ZooKeeper;
zkCli.cmd -server 127.0.0.1:2181
- 通過(guò)
help可以命令查看ZooKeeper的常用命令;
[zk: 127.0.0.1:2181(CONNECTED) 0] help
ZooKeeper -server host:port -client-configuration properties-file cmd args
addWatch [-m mode] path # optional mode is one of [PERSISTENT, PERSISTENT_RECURSIVE] - default is PERSISTENT_RECURSIVE
addauth scheme auth
close
config [-c] [-w] [-s]
connect host:port
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
delete [-v version] path
deleteall path [-b batch size]
delquota [-n|-b|-N|-B] path
get [-s] [-w] path
getAcl [-s] path
getAllChildrenNumber path
getEphemerals path
history
listquota path
ls [-s] [-w] [-R] path
printwatches on|off
quit
reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
redo cmdno
removewatches path [-c|-d|-a] [-l]
set [-s] [-v version] path data
setAcl [-s] [-v version] [-R] path acl
setquota -n|-b|-N|-B val path
stat [-w] path
sync path
version
whoami
- 大家都知道Redis是通過(guò)
key-value的形式存儲(chǔ)數(shù)據(jù)的,而ZooKeeper是通過(guò)znode-value的形式存儲(chǔ)數(shù)據(jù)的,znode有點(diǎn)像目錄,而/目錄就是ZooKeeper中的根目錄,通過(guò)如下命令可以查看所有znode;
[zk: 127.0.0.1:2181(CONNECTED) 1] ls /
[zookeeper]
- 創(chuàng)建一個(gè)znode叫做
/zk_test,存儲(chǔ)字符串my_data,這用起來(lái)有點(diǎn)像Redis;
[zk: 127.0.0.1:2181(CONNECTED) 2] create /zk_test my_data
Created /zk_test
- 查看所有znode,可以看到
zk_test這個(gè)znode;
[zk: 127.0.0.1:2181(CONNECTED) 3] ls /
[zk_test, zookeeper]
- 獲取znode中存儲(chǔ)的數(shù)據(jù);
[zk: 127.0.0.1:2181(CONNECTED) 4] get /zk_test
my_data
- 修改znode中的數(shù)據(jù);
[zk: 127.0.0.1:2181(CONNECTED) 5] set /zk_test test_data
[zk: 127.0.0.1:2181(CONNECTED) 6] get /zk_test
test_data
- 刪除znode中的數(shù)據(jù);
[zk: 127.0.0.1:2181(CONNECTED) 7] delete /zk_test
[zk: 127.0.0.1:2181(CONNECTED) 8] ls /
[zookeeper]
可視化管理
PrettyZoo是一款基于 Apache Curator 和 JavaFX 實(shí)現(xiàn)的 Zookeeper 圖形化管理客戶端。顏值很高,推薦使用。
- 首先下載
PrettyZoo的安裝包,下載地址:https://github.com/vran-dev/PrettyZoo/releasesimage.png - 我們需要?jiǎng)?chuàng)建一個(gè)連接,連接到ZooKeeper,可以發(fā)現(xiàn)
PrettyZoo是支持通過(guò)SSH通道連接的;image.png -
雙擊連接,我們可以查看到ZooKeeper中存儲(chǔ)的數(shù)據(jù),很清楚的發(fā)現(xiàn),ZooKeeper是按目錄結(jié)構(gòu)存儲(chǔ)數(shù)據(jù)的;image.png
-
右鍵目錄,我們可以創(chuàng)建和刪除znode,有了這個(gè)工具,基本上可以和命令行操作說(shuō)再見了;image.png
- 如果你還是覺得命令行比較炫酷的話,
PrettyZoo也實(shí)現(xiàn)了命令行功能,打開命令行標(biāo)簽就可以愉快地敲命令了。image.png
節(jié)點(diǎn)類型
ZooKeeper中的節(jié)點(diǎn)(znode)是有生命周期的,這取決于節(jié)點(diǎn)的類型。類型有主要有下面四種:
- 持久節(jié)點(diǎn)(Persistent):默認(rèn)節(jié)點(diǎn)類型,節(jié)點(diǎn)創(chuàng)建后,會(huì)一直存在。
- 持久順序節(jié)點(diǎn)(Persistent Sequential):具有持久節(jié)點(diǎn)特性,節(jié)點(diǎn)名稱后會(huì)增加自增數(shù)字后綴。
- 臨時(shí)節(jié)點(diǎn)(Ephemeral):臨時(shí)存在,當(dāng)創(chuàng)建節(jié)點(diǎn)的會(huì)話關(guān)閉時(shí),節(jié)點(diǎn)被刪除。
- 臨時(shí)順序節(jié)點(diǎn)(Ephemeral Sequential):具有臨時(shí)節(jié)點(diǎn)特性,節(jié)點(diǎn)名稱后會(huì)增加自增數(shù)字后綴。
如果你用命令行創(chuàng)建節(jié)點(diǎn)的話,順序特性對(duì)應(yīng)-s選項(xiàng),臨時(shí)特性對(duì)應(yīng)-e選項(xiàng),比如如下命令:
# 創(chuàng)建持久順序節(jié)點(diǎn)
create -s /test/seq segText
# 創(chuàng)建臨時(shí)節(jié)點(diǎn)
create -e /test/tmp tmpText
# 創(chuàng)建臨時(shí)順序節(jié)點(diǎn)
create -s -e /test/seqTmp setTmpText
創(chuàng)建成功后顯示如下:

如果你用
PrettyZoo來(lái)創(chuàng)建的話,只要勾選一個(gè)選項(xiàng)即可。
作為注冊(cè)中心使用
CAP是分布式架構(gòu)中的重要理論,其包括一致性(Consistency)、可用性(Availability)和分區(qū)容忍性(Partition tolerance)。我們經(jīng)常使用的Eureka支持AP,而ZooKeeper支持CP。接下來(lái)我們學(xué)習(xí)下ZooKeeper在Spring Cloud中作為注冊(cè)中心的應(yīng)用。
- ZooKeeper作為注冊(cè)中心使用,用法基本和Eureka和Consul相同,首先我們需要在
pom.xml中添加ZooKeeper的服務(wù)發(fā)現(xiàn)組件;
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
- 之后修改配置文件
application.yml,添加ZooKeeper相關(guān)配置;
spring:
cloud:
zookeeper:
# zookeeper連接地址
connect-string: localhost:2181
discovery:
# 作為服務(wù)注冊(cè)
register: true
# 注冊(cè)時(shí)使用IP地址而不是hostname
prefer-ip-address: true
-
這里還是使用《Spring Cloud學(xué)習(xí)教程》中的例子,有兩個(gè)服務(wù)
zookeeper-ribbon-service和zookeeper-user-service,前者通過(guò)Ribbon遠(yuǎn)程調(diào)用后者;image.png -
分別啟動(dòng)兩個(gè)服務(wù),我們通過(guò)
PrettyZoo可以發(fā)現(xiàn),當(dāng)ZooKeeper作為注冊(cè)中心時(shí),注冊(cè)服務(wù)的名稱、IP、端口都被存儲(chǔ)到了里面;image.png -
我們調(diào)用
zookeeper-ribbon-service中的接口測(cè)試下,發(fā)現(xiàn)可以正常訪問(wèn),接口地址:http://localhost:8301/user/1image.png -
如果這時(shí)候我們把
zookeeper-user-service服務(wù)關(guān)掉的話,我們可以發(fā)現(xiàn)ZooKeeper會(huì)自動(dòng)刪除存儲(chǔ)的數(shù)據(jù);image.png 由此可以看出,ZooKeeper作為微服務(wù)的注冊(cè)中心是通過(guò)臨時(shí)節(jié)點(diǎn)來(lái)實(shí)現(xiàn)的,當(dāng)服務(wù)上線時(shí)會(huì)向ZooKeeper中注冊(cè),當(dāng)服務(wù)下線時(shí)會(huì)被ZooKeeper刪除,保障了微服務(wù)的高可用。
總結(jié)
今天我們學(xué)習(xí)了下ZooKeeper的安裝、可視化工具PrettyZoo的使用以及ZooKeeper在Spring Cloud中作為注冊(cè)中心的應(yīng)用。其實(shí)ZooKeeper在分布式系統(tǒng)中還有很多應(yīng)用,比如說(shuō)做分布式鎖、實(shí)現(xiàn)選主功能、取代UUID來(lái)生成唯一ID,大家感興趣的話可以深入研究下!
參考資料
官方文檔:https://zookeeper.apache.org/doc/current/zookeeperStarted.html










