分布式協(xié)調(diào)服務(wù)之Zookeeper集群部署
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
? 作者?|??Linux-1874
來源 |? urlify.cn/FNFBRr
66套java從入門到精通實(shí)戰(zhàn)課程分享
一、分布式系統(tǒng)概念
在聊Zookeeper之前,我們先來聊聊什么是分布式系統(tǒng);所謂分布式系統(tǒng)就是一個(gè)系統(tǒng)的軟件或硬件組件分布在網(wǎng)絡(luò)中的不同計(jì)算機(jī)之上,彼此間通過消息傳遞進(jìn)行通信和協(xié)作的系統(tǒng);簡單講就是一個(gè)系統(tǒng)的組件分布在不同網(wǎng)絡(luò)中的各主機(jī)上,彼此通過消息傳遞通信和協(xié)作,我們把這樣的系統(tǒng)就叫做分布式系統(tǒng);
二、分布式系統(tǒng)的特征
1、分布性:所謂分布性就是指我們在上面描述的各組件分布在不同的網(wǎng)絡(luò)中的不同計(jì)算機(jī)上;
2、對等性:所謂對等性是指不同計(jì)算節(jié)點(diǎn)上的組件沒有主從之分,所有組件的角色身份都是平等的;
3、并發(fā)性:指集群中的各節(jié)點(diǎn)同時(shí)對一些資源進(jìn)行并發(fā)訪問;各節(jié)點(diǎn)同時(shí)并發(fā)訪問一些資源,如何協(xié)調(diào)這些節(jié)點(diǎn)對同一資源的訪問是一個(gè)分布式系統(tǒng)面臨的一個(gè)問題;
4、缺乏全局時(shí)鐘:集群各節(jié)點(diǎn)組件沒有一個(gè)全局時(shí)鐘;
5、故障必然會發(fā)生:這個(gè)是說一個(gè)分布式系統(tǒng)中的各個(gè)節(jié)點(diǎn)一定會故障發(fā)生;
三、分布式系統(tǒng)常見的故障
1、通信異常:集群各節(jié)點(diǎn)都是通過網(wǎng)絡(luò)通信,如果因各網(wǎng)絡(luò)設(shè)備故障或異常,或者網(wǎng)絡(luò)線路故障都可導(dǎo)致通信異常;
2、網(wǎng)絡(luò)分區(qū):在發(fā)生通信異常后,各節(jié)點(diǎn)間通信延遲變得越來越高,最終會導(dǎo)致一個(gè)分布式系統(tǒng)的所有節(jié)點(diǎn)中,一部分能夠正常通信,一部分不能正常通信,我們把這種現(xiàn)象叫做網(wǎng)絡(luò)發(fā)生了分區(qū);比如,兩臺server組成的集群,當(dāng)其中一臺server不能夠正常的聯(lián)系到另一臺server,這個(gè)時(shí)候我們就說網(wǎng)絡(luò)發(fā)生了分區(qū);對于網(wǎng)絡(luò)分區(qū),如何界定哪臺server的網(wǎng)絡(luò)故障就先得尤為重要;
3、三態(tài):指在分布式系統(tǒng)中各組件間的每一次請求和應(yīng)答狀態(tài);如果能夠正常響應(yīng)請求我們就說本次請求成功被響應(yīng);反之,我們就說本次請求失敗;除了這兩種狀態(tài)外,還有第三種,在分布式系統(tǒng)中網(wǎng)絡(luò)是不可靠因素,因此各組件間調(diào)用就很有可能存在超時(shí);所謂超時(shí)是指在一定時(shí)間范圍內(nèi)請求一直沒有得到響應(yīng);
4、節(jié)點(diǎn)故障:指分布式系統(tǒng)中各節(jié)點(diǎn)因各種原因?qū)е鹿?jié)點(diǎn)故障;比如節(jié)點(diǎn)斷電宕機(jī),人為操作不當(dāng)?shù)鹊龋?/span>
四、CAP理論和BASE理論
CAP理論指一個(gè)分布式系統(tǒng)中,一致性(Consistency)、可用性(Availability)、分區(qū)容錯(cuò)性(Partition tolerance);這三個(gè)要素最多只能同時(shí)滿足兩個(gè);這樣一來我們的系統(tǒng)要么滿足一致性和可用性,要么滿足一致性和分區(qū)容錯(cuò)性,要么滿足可用性和分區(qū)容錯(cuò)性;我們知道一個(gè)分布式系統(tǒng)各組件間傳遞消息來通信,所以網(wǎng)絡(luò)分區(qū)容錯(cuò)性應(yīng)該必須滿足;這樣一來我們的系統(tǒng)就必須在一致性和可用性之間做權(quán)衡;
BASE理論:BA表示基本可用,S表示軟狀態(tài),E表示最終一致性;它主要是對CAP理論中的一致性和可用性進(jìn)行權(quán)衡的結(jié)果;意思是說一個(gè)分布式系統(tǒng)應(yīng)該滿足系統(tǒng)基本可用(允許部分節(jié)點(diǎn)不可用),在一定時(shí)間窗口內(nèi)我們允許各節(jié)點(diǎn)之間數(shù)據(jù)不一致,但要保證最終一致;
五、zookeeper簡介
zookeeper是一個(gè)開源的分布式協(xié)調(diào)服務(wù),由知名互聯(lián)網(wǎng)公司Yahoo創(chuàng)建,它是Chubby的開源實(shí)現(xiàn);換句話講,zookeeper是一個(gè)典型的分布式數(shù)據(jù)一致性解決方案,分布式應(yīng)用程序可以基于它實(shí)現(xiàn)數(shù)據(jù)的發(fā)布/訂閱、負(fù)載均衡、名稱服務(wù)、分布式協(xié)調(diào)/通知、集群管理、Master選舉、分布式鎖和分布式隊(duì)列;
zookeeper集群中的相關(guān)概念
集群角色:Leader、Follower、Observer;一個(gè)zookeeper(簡稱zk)集群,是由一個(gè)leader,多個(gè)Follower和Observer角色組成;其中Leader是由follower和observer選舉產(chǎn)生,提供讀寫服務(wù);Leader參與選舉,能夠被選舉,提供讀服務(wù);Observer參與選舉,不能夠被選舉,提供讀服務(wù);
zk會話:指客戶端和服務(wù)端建立的tcp長鏈接;
數(shù)據(jù)節(jié)點(diǎn)(ZNode):即zk數(shù)據(jù)模型中的數(shù)據(jù)單元;zk的數(shù)據(jù)都存儲于內(nèi)存中,數(shù)據(jù)模型為樹狀結(jié)構(gòu)(ZNode Tree);每個(gè)ZNode都會保存自己的數(shù)據(jù)于內(nèi)存中;其中ZNode節(jié)點(diǎn)又分持久節(jié)點(diǎn)和臨時(shí)節(jié)點(diǎn),所謂持久節(jié)點(diǎn)指僅顯式刪除才消失的節(jié)點(diǎn);臨時(shí)節(jié)點(diǎn)指會話中止即自動(dòng)消失的節(jié)點(diǎn);
版本(version):ZK會為每個(gè)ZNode維護(hù)一個(gè)稱之為Stat的數(shù)據(jù)結(jié)構(gòu),記錄了當(dāng)前ZNode的三個(gè)數(shù)據(jù)版本;當(dāng)前版本(version),當(dāng)前znode的子節(jié)點(diǎn)的版本(cversion),當(dāng)前znode的ACL的版本(aversion);
ACL:ZK使用ACL機(jī)制進(jìn)行權(quán)限控制;CREATE, READ,WRITE,DELETE,ADMIN;
事件監(jiān)聽器(Watcher):ZK上,由用戶指定的觸發(fā)機(jī)制,在某些事件產(chǎn)生時(shí),ZK能夠?qū)⑼ㄖo相關(guān)的客戶端;
ZAB協(xié)議:Zookeeper Atomic Broadcast,ZK原子廣播協(xié)議;Zab協(xié)議是為分布式協(xié)調(diào)服務(wù)Zookeeper專門設(shè)計(jì)的一種 支持崩潰恢復(fù)的原子廣播協(xié)議;?主要作用是在zk集群leader崩潰以后,能夠基于此協(xié)議選舉新leader,并且保證數(shù)據(jù)最終一致性和完整性;zk客戶端連接zk集群中的任何一個(gè)節(jié)點(diǎn),發(fā)起請求,如果客戶端發(fā)送讀請求,則直接由當(dāng)前節(jié)點(diǎn)響應(yīng);如果客戶端發(fā)送的是寫請求,且當(dāng)前節(jié)點(diǎn)不是leader節(jié)點(diǎn),則由當(dāng)前節(jié)點(diǎn)把寫請求,轉(zhuǎn)發(fā)給leader,由leader進(jìn)行寫事務(wù)廣播,只有超過集群節(jié)點(diǎn)半數(shù)的響應(yīng)允許寫,該事務(wù)才會被并提交;只有當(dāng)leader寫成功后,leader會通知各follower來同步數(shù)據(jù);對于zab協(xié)議來講,它存在三種狀態(tài),分別是Looking,F(xiàn)ollowing和Leading;所謂looking狀態(tài)指zk集群正在啟動(dòng)或leader崩潰以后,各節(jié)點(diǎn)進(jìn)行選舉的過程時(shí)的狀態(tài);following狀態(tài)指當(dāng)zk集群中有l(wèi)eader以后,各個(gè)follower的狀態(tài);leading狀態(tài)就是指leader所屬狀態(tài);所以zk集群中的各節(jié)點(diǎn)都會在這三個(gè)狀態(tài)上來回轉(zhuǎn)換,在集群剛啟動(dòng)或leder崩潰以后,各節(jié)點(diǎn)都會切換為looking狀態(tài),在選舉產(chǎn)生leader以后,當(dāng)選leader的節(jié)點(diǎn)會從looking切換為leading狀態(tài),其他follower會從looking切換為following狀態(tài);只要zk集群觸發(fā)一次新的選舉,都會經(jīng)過上述狀態(tài)的轉(zhuǎn)換;
六、zookeeper集群部署
環(huán)境說明
| 主機(jī)名 | ip地址 |
| node01 | 192.168.0.41 |
| node02 | 192.168.0.42 |
| node03 | 192.168.0.43 |
1、集群各節(jié)點(diǎn)安裝jdk
[root@node01?~]#?yum?install?-y?java-1.8.0-openjdk-devel
提示:各節(jié)點(diǎn)的時(shí)間同步、selinux、iptables和firewalld服務(wù)的配置都要提前做好;
驗(yàn)證:在各節(jié)點(diǎn)執(zhí)行java -version看看對應(yīng)java的版本是不是我們安裝的版本?

提示:只要在各節(jié)點(diǎn)上能夠看到對應(yīng)版本的java信息出現(xiàn),并且是我們指定的版本,說明java環(huán)境沒有問題;
2、下載zookeeper二進(jìn)制包
[root@node01?~]#?cd?/usr/local/
[root@node01?local]#?ll
total?0
drwxr-xr-x.?2?root?root??6?Nov??5??2016?bin
drwxr-xr-x.?2?root?root??6?Nov??5??2016?etc
drwxr-xr-x.?2?root?root??6?Nov??5??2016?games
drwxr-xr-x.?2?root?root??6?Nov??5??2016?include
drwxr-xr-x.?2?root?root??6?Nov??5??2016?lib
drwxr-xr-x.?2?root?root??6?Nov??5??2016?lib64
drwxr-xr-x.?2?root?root??6?Nov??5??2016?libexec
drwxr-xr-x.?2?root?root??6?Nov??5??2016?sbin
drwxr-xr-x.?5?root?root?49?Sep?15?20:33?share
drwxr-xr-x.?2?root?root??6?Oct?19?19:42?src
[root@node01?local]#?wget?https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.6.2/apache-zookeeper-3.6.2-bin.tar.gz
--2020-10-19?19:42:52--??https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.6.2/apache-zookeeper-3.6.2-bin.tar.gz
Resolving?mirrors.tuna.tsinghua.edu.cn?(mirrors.tuna.tsinghua.edu.cn)...?101.6.8.193,?2402:f000:1:408:8100::1
Connecting?to?mirrors.tuna.tsinghua.edu.cn?(mirrors.tuna.tsinghua.edu.cn)|101.6.8.193|:443...?connected.
HTTP?request?sent,?awaiting?response...?200?OK
Length:?12515974?(12M)?[application/x-gzip]
Saving?to:?‘a(chǎn)pache-zookeeper-3.6.2-bin.tar.gz’
?
100%[================================================================================>]?12,515,974??4.02MB/s???in?3.0s??
?
2020-10-19?19:42:55?(4.02?MB/s)?-?‘a(chǎn)pache-zookeeper-3.6.2-bin.tar.gz’?saved?[12515974/12515974]
?
[root@node01?local]#?ll
total?12224
-rw-r--r--??1?root?root?12515974?Sep??9?19:36?apache-zookeeper-3.6.2-bin.tar.gz
drwxr-xr-x.?2?root?root????????6?Nov??5??2016?bin
drwxr-xr-x.?2?root?root????????6?Nov??5??2016?etc
drwxr-xr-x.?2?root?root????????6?Nov??5??2016?games
drwxr-xr-x.?2?root?root????????6?Nov??5??2016?include
drwxr-xr-x.?2?root?root????????6?Nov??5??2016?lib
drwxr-xr-x.?2?root?root????????6?Nov??5??2016?lib64
drwxr-xr-x.?2?root?root????????6?Nov??5??2016?libexec
drwxr-xr-x.?2?root?root????????6?Nov??5??2016?sbin
drwxr-xr-x.?5?root?root???????49?Sep?15?20:33?share
drwxr-xr-x.?2?root?root????????6?Oct?19?19:42?src
[root@node01?local]#?scp?apache-zookeeper-3.6.2-bin.tar.gz?node02:/usr/local/
apache-zookeeper-3.6.2-bin.tar.gz???????????????????????????????????????????????????????100%???12MB??26.8MB/s???00:00???
[root@node01?local]#?scp?apache-zookeeper-3.6.2-bin.tar.gz?node03:/usr/local/
apache-zookeeper-3.6.2-bin.tar.gz???????????????????????????????????????????????????????100%???12MB??32.7MB/s???00:00???
[root@node01?local]#
解壓二進(jìn)制包,并把解壓后的目錄做軟鏈接

提示:其他兩個(gè)節(jié)點(diǎn)都要做相同的操作;
3、配置zookeeper

提示:zookeeper在二進(jìn)制包中給我們提供了一個(gè)示例配置文件其路徑為conf/下名為zoo_sample.cfg,我們需要將其復(fù)制為zoo.cfg,然后基于此文件做修改即可;這里主要修改dataDir,從名字上我們可以知道,這個(gè)參數(shù)是指定zookeeper的數(shù)據(jù)目錄;上面的tickTime用于指定節(jié)點(diǎn)向leader發(fā)送心跳的間隔時(shí)間,單位毫秒,一般不用改;initLimit用于指定初始化階段要經(jīng)過多個(gè)tickTime時(shí)長;超出則為初始化超時(shí)或初始化失?。籹yncLimit用戶指定同步階段需要經(jīng)過多少個(gè)tickTime時(shí)長,超出指定的時(shí)長,則為同步失敗,或同步超時(shí);clientPort用于指定客戶端連接zk集群所用端口,即zk集群客戶監(jiān)聽端口;后面的server.1使用于配置集群第一個(gè)節(jié)點(diǎn)的信息;其語法格式為server.id=[hostname or ipaddr ]:port:port[:observer];其中第一個(gè)port用于指定follower與leader進(jìn)行通信和數(shù)據(jù)同步時(shí)所使用端口;第二個(gè)port是指定leader選舉時(shí)使用的端口;集群中有多少zk主機(jī)就要配置多少個(gè)server,并且每個(gè)server的ID必須唯一,除此之外對應(yīng)在配置文件中配置的serverID必須同對應(yīng)server上的數(shù)據(jù)目錄下的myid文件內(nèi)容中的ID保持一致;
zk配置參數(shù)說明
除了以上配置,zk還有其他配置
存儲配置:
??????????????? preAllocSize:為事務(wù)日志預(yù)先分配的磁盤空間量;默認(rèn)65535KB;
??????????????? snapCount:每多少次事務(wù)后執(zhí)行一次快照操作;每事務(wù)的平均大小在100字節(jié);
??????????????? autopurget.snapRetainCount:自動(dòng)清理快照時(shí),需要保存最近的快照個(gè)數(shù);
??????????????? autopurge.purgeInterval:purge操作的時(shí)間間隔,0表示不啟動(dòng);
??????????????? fsync.warningthresholdms:zk進(jìn)行事務(wù)日志fsync操作時(shí)消耗的時(shí)長報(bào)警閾值;
??????????????? weight.X=N:判斷quorum時(shí)投票權(quán)限,默認(rèn)1;
????????????????
????????????網(wǎng)絡(luò)配置:
??????????????? maxClientCnxns:每客戶端IP的最大并發(fā)連接數(shù);
??????????????? clientPortAddress:zk監(jiān)聽IP地址;
??????????????? minSessionTimeout:會話的最短超時(shí)時(shí)長;
??????????????? maxSessionTimeout:會話的最大超時(shí)時(shí)長
????????????????
????????????集群配置:
??????????????? initLimit:Follower連入Leader并完成數(shù)據(jù)同步的時(shí)長;
??????????????? syncLimit:心跳檢測的最大延遲;
??????????????? leaderServes:默認(rèn)zk的leader接收讀寫請求,額外還要負(fù)責(zé)協(xié)調(diào)各Follower發(fā)來的事務(wù)等;因此,為使得leader集中處理zk集群內(nèi)部信息,建議不讓leader直接提供服務(wù);
??????????????? cnxTimeout:Leader選舉期間,各服務(wù)器創(chuàng)建TCP連接的超時(shí)時(shí)長;
??????????????? ellectionAlg:選舉算法,目前僅支持FastLeaderElection算法一種;
復(fù)制配置文件到集群各節(jié)點(diǎn),創(chuàng)建數(shù)據(jù)目錄并在其數(shù)據(jù)目錄下各自創(chuàng)建用于保存節(jié)點(diǎn)id的myid文件,其內(nèi)容僅為當(dāng)前節(jié)點(diǎn)的server id
[root@node01?conf]#?scp?zoo.cfg?node02:/usr/local/zookeeper/conf/
zoo.cfg?????????????????????????????????????????????????????????????????????????????????100%?1244???412.3KB/s???00:00???
[root@node01?conf]#?scp?zoo.cfg?node03:/usr/local/zookeeper/conf/
zoo.cfg?????????????????????????????????????????????????????????????????????????????????100%?1244???486.7KB/s???00:00???
[root@node01?conf]#?mkdir?/data/zookeeper?-pv
mkdir:?created?directory?‘/data’
mkdir:?created?directory?‘/data/zookeeper’
[root@node01?conf]#?echo?1?>/data/zookeeper/myid
[root@node01?conf]#?cat?/data/zookeeper/myid
1
[root@node01?conf]#?ssh?node02?'mkdir?-pv?/data/zookeeper/?&&?echo?2?>/data/zookeeper/myid?&&?cat?/data/zookeeper/myid'
mkdir:?created?directory?‘/data’
mkdir:?created?directory?‘/data/zookeeper/’
2
[root@node01?conf]#?ssh?node03?'mkdir?-pv?/data/zookeeper/?&&?echo?3?>/data/zookeeper/myid?&&?cat?/data/zookeeper/myid'?
mkdir:?created?directory?‘/data’
mkdir:?created?directory?‘/data/zookeeper/’
3
[root@node01?conf]#
提示:這里的myid中的server id是根據(jù)其配置文件中配置的server id,意思就是主配置文件中的server id 要和其當(dāng)前主節(jié)點(diǎn)中的myid保持一致,否則zk集群啟動(dòng)不了;如果只有一臺zkserver,可以只配置單臺zkserver的屬性信息,不用在其數(shù)據(jù)目錄下創(chuàng)建myid保存serverID;
在各節(jié)點(diǎn)啟動(dòng)zookeeper
[root@node01?~]#?/usr/local/zookeeper/bin/zkServer.sh?--help
/usr/bin/java
ZooKeeper?JMX?enabled?by?default
Using?config:?/usr/local/zookeeper/bin/../conf/zoo.cfg
Usage:?/usr/local/zookeeper/bin/zkServer.sh?[--config?]?{start|start-foreground|stop|version|restart|status|print-cmd}
[root@node01?~]#?/usr/local/zookeeper/bin/zkServer.sh?start
/usr/bin/java
ZooKeeper?JMX?enabled?by?default
Using?config:?/usr/local/zookeeper/bin/../conf/zoo.cfg
Starting?zookeeper?...?STARTED
[root@node01?~]#?ssh?node02?'/usr/local/zookeeper/bin/zkServer.sh?start'
/usr/bin/java
ZooKeeper?JMX?enabled?by?default
Using?config:?/usr/local/zookeeper/bin/../conf/zoo.cfg
Starting?zookeeper?...?STARTED
[root@node01?~]#?ssh?node03?'/usr/local/zookeeper/bin/zkServer.sh?start'
/usr/bin/java
ZooKeeper?JMX?enabled?by?default
Using?config:?/usr/local/zookeeper/bin/../conf/zoo.cfg
Starting?zookeeper?...?STARTED
[root@node01?~]#?ss?-tnl
State??????Recv-Q?Send-Q????????????????Local?Address:Port???????????????????????????????Peer?Address:Port?????????????
LISTEN?????0??????128???????????????????????????????*:22????????????????????????????????????????????*:*?????????????????
LISTEN?????0??????100???????????????????????127.0.0.1:25????????????????????????????????????????????*:*?????????????????
LISTEN?????0??????50??????????????::ffff:192.168.0.41:3888?????????????????????????????????????????:::*?????????????????
LISTEN?????0??????50???????????????????????????????:::8080?????????????????????????????????????????:::*?????????????????
LISTEN?????0??????128??????????????????????????????:::22???????????????????????????????????????????:::*?????????????????
LISTEN?????0??????100?????????????????????????????::1:25???????????????????????????????????????????:::*?????????????????
LISTEN?????0??????50???????????????????????????????:::2181?????????????????????????????????????????:::*?????????????????
LISTEN?????0??????50???????????????????????????????:::35879????????????????????????????????????????:::*?????????????????
[root@node01?~]#
提示:可以看到node01上3888、2181、8080這三個(gè)端口都處于監(jiān)聽狀態(tài)了;8080是jetty監(jiān)聽的端口,用于管理用,如果修改其監(jiān)聽端口可以在配置文件中加admin.serverPort=來定義即可;
node02上監(jiān)聽端口情況
[root@node02?local]#?ss?-tnl
State??????Recv-Q?Send-Q????????????????Local?Address:Port???????????????????????????????Peer?Address:Port?????????????
LISTEN?????0??????128???????????????????????????????*:22????????????????????????????????????????????*:*?????????????????
LISTEN?????0??????100???????????????????????127.0.0.1:25????????????????????????????????????????????*:*?????????????????
LISTEN?????0??????50??????????????::ffff:192.168.0.42:3888?????????????????????????????????????????:::*?????????????????
LISTEN?????0??????50???????????????????????????????:::8080?????????????????????????????????????????:::*?????????????????
LISTEN?????0??????128??????????????????????????????:::22???????????????????????????????????????????:::*?????????????????
LISTEN?????0??????100?????????????????????????????::1:25???????????????????????????????????????????:::*?????????????????
LISTEN?????0??????50???????????????????????????????:::2181?????????????????????????????????????????:::*?????????????????
LISTEN?????0??????50???????????????????????????????:::35589????????????????????????????????????????:::*?????????????????
LISTEN?????0??????50??????????????::ffff:192.168.0.42:2888?????????????????????????????????????????:::*?????????????????
[root@node02?local]#
提示:node02相對node01多監(jiān)聽了一個(gè)2888端口,這個(gè)端口只有l(wèi)eader節(jié)點(diǎn)才會監(jiān)聽,從查看端口的情況就可以判斷node02此時(shí)是leader節(jié)點(diǎn);
node03上監(jiān)聽端口情況
[root@node03?local]#?ss?-tnl
State??????Recv-Q?Send-Q????????????????Local?Address:Port???????????????????????????????Peer?Address:Port?????????????
LISTEN?????0??????128???????????????????????????????*:22????????????????????????????????????????????*:*?????????????????
LISTEN?????0??????100???????????????????????127.0.0.1:25????????????????????????????????????????????*:*?????????????????
LISTEN?????0??????50??????????????::ffff:192.168.0.43:3888?????????????????????????????????????????:::*?????????????????
LISTEN?????0??????50???????????????????????????????:::8080?????????????????????????????????????????:::*?????????????????
LISTEN?????0??????128??????????????????????????????:::22???????????????????????????????????????????:::*?????????????????
LISTEN?????0??????100?????????????????????????????::1:25???????????????????????????????????????????:::*?????????????????
LISTEN?????0??????50???????????????????????????????:::46683????????????????????????????????????????:::*?????????????????
LISTEN?????0??????50???????????????????????????????:::2181?????????????????????????????????????????:::*?????????????????
[root@node03?local]#
提示:node03和node01一樣,都沒有監(jiān)聽2888端口,說明這兩個(gè)幾點(diǎn)是follower節(jié)點(diǎn);到此一個(gè)三節(jié)點(diǎn)的zookeeper集群就搭建好了;
測試:使用zkServer.sh status查看當(dāng)前節(jié)點(diǎn)狀態(tài)

提示:可以看到node02是leader;
把node02的zk重啟,看看它是否還是leader?

提示:可以看到當(dāng)node02重啟后,再次加入集群就不再是leader了;
使用zkCli.sh連接zk
[zk:?localhost:2181(CONNECTED)?0]??
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]?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?val?path
????????stat?[-w]?path
????????sync?path
????????version
Command?not?found:?Command?not?found??
[zk:?localhost:2181(CONNECTED)?1]
提示:在集群任意一個(gè)節(jié)點(diǎn)使用zkCli.sh 即可連接當(dāng)前節(jié)點(diǎn)的2181端口;連接以后會有一個(gè)zk的控制臺,我們輸入一個(gè)不存在的命令,可打印在當(dāng)前控制臺上所使用的命令有哪些;
查看數(shù)據(jù)節(jié)點(diǎn)
[zk:?localhost:2181(CONNECTED)?1]?ls
ls?[-s]?[-w]?[-R]?path
[zk:?localhost:2181(CONNECTED)?2]?ls?/
[zookeeper]
[zk:?localhost:2181(CONNECTED)?3]
提示:zk的數(shù)據(jù)節(jié)點(diǎn)類似Linux文件系統(tǒng),它也是一顆倒置的樹狀結(jié)構(gòu);
創(chuàng)建一個(gè)數(shù)據(jù)節(jié)點(diǎn),并給一個(gè)數(shù)據(jù)內(nèi)容將其存入到創(chuàng)建的節(jié)點(diǎn)
[zk:?localhost:2181(CONNECTED)?11]?create?/test?"test01"
Created?/test
[zk:?localhost:2181(CONNECTED)?12]?ls?/
[test,?zookeeper]
[zk:?localhost:2181(CONNECTED)?13]
查看/test節(jié)點(diǎn)的數(shù)據(jù) 提示:默認(rèn)不指定任何選項(xiàng),創(chuàng)建的節(jié)點(diǎn)都是持久節(jié)點(diǎn),即會話斷開對應(yīng)節(jié)點(diǎn)不會自動(dòng)刪除;如果需要?jiǎng)?chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn)需要用到-e選項(xiàng)來明確指定創(chuàng)建一個(gè)臨時(shí)節(jié)點(diǎn);
[zk:?localhost:2181(CONNECTED)?13]?get?/test
test01
[zk:?localhost:2181(CONNECTED)?14]修改/test節(jié)點(diǎn)的數(shù)據(jù)
[zk:?localhost:2181(CONNECTED)?14]?set?/test?"test?data?version?2"
[zk:?localhost:2181(CONNECTED)?15]?get?/test
test?data?version?2
[zk:?localhost:2181(CONNECTED)?16]刪除/test節(jié)點(diǎn)
[zk:?localhost:2181(CONNECTED)?16]?delete?/test
[zk:?localhost:2181(CONNECTED)?17]?ls?/
[zookeeper]
[zk:?localhost:2181(CONNECTED)?18]提示:delete是刪除一個(gè)下面沒有子節(jié)點(diǎn)的節(jié)點(diǎn),如果對應(yīng)節(jié)點(diǎn)下還有子節(jié)點(diǎn),需要用到deleteall來刪除;
刪除帶有子節(jié)點(diǎn)的節(jié)點(diǎn)
[zk:?localhost:2181(CONNECTED)?25]?ls?/
[zookeeper]
[zk:?localhost:2181(CONNECTED)?26]?create?/test?"test01"
Created?/test
[zk:?localhost:2181(CONNECTED)?27]?ls?/
[test,?zookeeper]
[zk:?localhost:2181(CONNECTED)?28]?create?/test/aa?"test02"
Created?/test/aa
[zk:?localhost:2181(CONNECTED)?29]?ls?/test
[aa]
[zk:?localhost:2181(CONNECTED)?30]?ls?-R?/test
/test
/test/aa
[zk:?localhost:2181(CONNECTED)?31]?delete?/test
Node?not?empty:?/test
[zk:?localhost:2181(CONNECTED)?32]?deleteall?/test
[zk:?localhost:2181(CONNECTED)?33]?ls?/
[zookeeper]
[zk:?localhost:2181(CONNECTED)?34]
提示:ls -R表示遞歸查看指定節(jié)點(diǎn)及其子節(jié)點(diǎn);
查看集群成員配置信息
[zk:?localhost:2181(CONNECTED)?38]?config
server.1=192.168.0.41:2888:3888:participant
server.2=192.168.0.42:2888:3888:participant
server.3=192.168.0.43:2888:3888:participant
version=0
[zk:?localhost:2181(CONNECTED)?39]查看指定節(jié)點(diǎn)的狀態(tài)信息
[zk:?localhost:2181(CONNECTED)?40]?stat
stat?[-w]?path
[zk:?localhost:2181(CONNECTED)?41]?stat?/
cZxid?=?0x0
ctime?=?Thu?Jan?01?08:00:00?CST?1970
mZxid?=?0x0
mtime?=?Thu?Jan?01?08:00:00?CST?1970
pZxid?=?0x200000014
cversion?=?9
dataVersion?=?0
aclVersion?=?0
ephemeralOwner?=?0x0
dataLength?=?0
numChildren?=?1
[zk:?localhost:2181(CONNECTED)?42zk四字命令使用
查看生效的配置
[root@node01?~]#?echo?conf?|nc?node01?2181??????????????????
conf?is?not?executed?because?it?is?not?in?the?whitelist.
[root@node01?~]#提示:默認(rèn)zk沒有開啟四字命令;需要到配置文件中配置4lw.commands.whitelist=*,然后保存重啟zk即可支持四字命令;

重啟zk,再來使用conf命令查看生效配置信息
[root@node01?~]#?/usr/local/zookeeper/bin/zkServer.sh?restart
/usr/bin/java
ZooKeeper?JMX?enabled?by?default
Using?config:?/usr/local/zookeeper/bin/../conf/zoo.cfg
/usr/bin/java
ZooKeeper?JMX?enabled?by?default
Using?config:?/usr/local/zookeeper/bin/../conf/zoo.cfg
Stopping?zookeeper?...?STOPPED
/usr/bin/java
ZooKeeper?JMX?enabled?by?default
Using?config:?/usr/local/zookeeper/bin/../conf/zoo.cfg
Starting?zookeeper?...?STARTED
[root@node01?~]#?echo?conf?|nc?node01?2181??????????????????
clientPort=2181
secureClientPort=-1
dataDir=/data/zookeeper/version-2
dataDirSize=134218360
dataLogDir=/data/zookeeper/version-2
dataLogSize=134218360
tickTime=2000
maxClientCnxns=60
minSessionTimeout=4000
maxSessionTimeout=40000
clientPortListenBacklog=-1
serverId=1
initLimit=10
syncLimit=5
electionAlg=3
electionPort=3888
quorumPort=2888
peerType=0
membership:
server.1=192.168.0.41:2888:3888:participant
server.2=192.168.0.42:2888:3888:participant
server.3=192.168.0.43:2888:3888:participant
version=0[root@node01?~]#查看當(dāng)前server上的zk連接信息
[root@node01?~]#?echo?cons?|?nc?node01?2181
?/192.168.0.41:58920[0](queued=0,recved=1,sent=0)
?
[root@node01?~]#測試zk是否能夠正常連接
[root@node01?~]#?echo?ruok?|?nc?node01?2181???
imok[root@node01?~]#提示:返回imok表示zk節(jié)點(diǎn)上可以正常連接的;
列出當(dāng)前zkserver的版本信息、數(shù)據(jù)接收/發(fā)送量、連接數(shù)、節(jié)點(diǎn)模式、Node數(shù)、最大/平均/最小延遲數(shù)
[root@node01?~]#?echo?srvr?|?nc?node01?2181???
Zookeeper?version:?3.6.2--803c7f1a12f85978cb049af5e4ef23bd8b688715,?built?on?09/04/2020?12:44?GMT
Latency?min/avg/max:?0/0.0/0
Received:?6
Sent:?5
Connections:?1
Outstanding:?0
Zxid:?0x200000016
Mode:?follower
Node?count:?5
[root@node01?~]#列出事件監(jiān)聽器的連接數(shù)和總數(shù)
[root@node01?~]#?echo?wchs?|nc?node01?2181
0?connections?watching?0?paths
Total?watches:0
[root@node01?~]#列出當(dāng)前zkserver的環(huán)境信息
[root@node01?~]#?echo?envi|?nc?node01?2181
Environment:
zookeeper.version=3.6.2--803c7f1a12f85978cb049af5e4ef23bd8b688715,?built?on?09/04/2020?12:44?GMT
host.name=node01.test.org
java.version=1.8.0_262
java.vendor=Oracle?Corporation
java.home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.262.b10-0.el7_8.x86_64/jre
java.class.path=/usr/local/zookeeper/bin/../zookeeper-server/target/classes:/usr/local/zookeeper/bin/../build/classes:/usr/local/zookeeper/bin/../zookeeper-server/target/lib/*.jar:/usr/local/zookeeper/bin/../build/lib/*.jar:/usr/local/zookeeper/bin/../lib/zookeeper-prometheus-metrics-3.6.2.jar:/usr/local/zookeeper/bin/../lib/zookeeper-jute-3.6.2.jar:/usr/local/zookeeper/bin/../lib/zookeeper-3.6.2.jar:/usr/local/zookeeper/bin/../lib/snappy-java-1.1.7.jar:/usr/local/zookeeper/bin/../lib/slf4j-log4j12-1.7.25.jar:/usr/local/zookeeper/bin/../lib/slf4j-api-1.7.25.jar:/usr/local/zookeeper/bin/../lib/simpleclient_servlet-0.6.0.jar:/usr/local/zookeeper/bin/../lib/simpleclient_hotspot-0.6.0.jar:/usr/local/zookeeper/bin/../lib/simpleclient_common-0.6.0.jar:/usr/local/zookeeper/bin/../lib/simpleclient-0.6.0.jar:/usr/local/zookeeper/bin/../lib/netty-transport-native-unix-common-4.1.50.Final.jar:/usr/local/zookeeper/bin/../lib/netty-transport-native-epoll-4.1.50.Final.jar:/usr/local/zookeeper/bin/../lib/netty-transport-4.1.50.Final.jar:/usr/local/zookeeper/bin/../lib/netty-resolver-4.1.50.Final.jar:/usr/local/zookeeper/bin/../lib/netty-handler-4.1.50.Final.jar:/usr/local/zookeeper/bin/../lib/netty-common-4.1.50.Final.jar:/usr/local/zookeeper/bin/../lib/netty-codec-4.1.50.Final.jar:/usr/local/zookeeper/bin/../lib/netty-buffer-4.1.50.Final.jar:/usr/local/zookeeper/bin/../lib/metrics-core-3.2.5.jar:/usr/local/zookeeper/bin/../lib/log4j-1.2.17.jar:/usr/local/zookeeper/bin/../lib/json-simple-1.1.1.jar:/usr/local/zookeeper/bin/../lib/jline-2.14.6.jar:/usr/local/zookeeper/bin/../lib/jetty-util-9.4.24.v20191120.jar:/usr/local/zookeeper/bin/../lib/jetty-servlet-9.4.24.v20191120.jar:/usr/local/zookeeper/bin/../lib/jetty-server-9.4.24.v20191120.jar:/usr/local/zookeeper/bin/../lib/jetty-security-9.4.24.v20191120.jar:/usr/local/zookeeper/bin/../lib/jetty-io-9.4.24.v20191120.jar:/usr/local/zookeeper/bin/../lib/jetty-http-9.4.24.v20191120.jar:/usr/local/zookeeper/bin/../lib/javax.servlet-api-3.1.0.jar:/usr/local/zookeeper/bin/../lib/jackson-databind-2.10.3.jar:/usr/local/zookeeper/bin/../lib/jackson-core-2.10.3.jar:/usr/local/zookeeper/bin/../lib/jackson-annotations-2.10.3.jar:/usr/local/zookeeper/bin/../lib/commons-lang-2.6.jar:/usr/local/zookeeper/bin/../lib/commons-cli-1.2.jar:/usr/local/zookeeper/bin/../lib/audience-annotations-0.5.0.jar:/usr/local/zookeeper/bin/../zookeeper-*.jar:/usr/local/zookeeper/bin/../zookeeper-server/src/main/resources/lib/*.jar:/usr/local/zookeeper/bin/../conf:
java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.io.tmpdir=/tmp
java.compiler=
os.name=Linux
os.arch=amd64
os.version=3.10.0-693.el7.x86_64
user.name=root
user.home=/root
user.dir=/root
os.memory.free=26MB
os.memory.max=889MB
os.memory.total=37MB
[root@node01?~]#好了,到此zk集群搭建就完成了,通常zk集群應(yīng)用的場景很多,比如分布式應(yīng)用程序可以基于它實(shí)現(xiàn)數(shù)據(jù)的發(fā)布/訂閱、負(fù)載均衡、名稱服務(wù)、分布式協(xié)調(diào)/通知、集群管理、Master選舉、分布式鎖和分布式隊(duì)列;很多分布式服務(wù)都可以借助zk集群做服務(wù)發(fā)現(xiàn)和服務(wù)注冊;
粉絲福利:108本java從入門到大神精選電子書領(lǐng)取
???
?長按上方鋒哥微信二維碼?2 秒 備注「1234」即可獲取資料
感謝點(diǎn)贊支持下哈?
