上一篇:087-BigData-15Hadoop階段小結(jié)
一官辈、ZooKeeper概述
1.1概述
Zookeeper是一個(gè)開源的分布式的,為分布式應(yīng)用提供協(xié)調(diào)服務(wù)的Apache項(xiàng)目遍坟。Hadoop和Hbase的重要組件拳亿。它是一個(gè)為分布式應(yīng)用提供一致性服務(wù)的軟件,提供的功能包括:配置維護(hù)愿伴、域名服務(wù)肺魁、分布式同步、組服務(wù)等隔节。
1.2 特點(diǎn)
1)Zookeeper:一個(gè)領(lǐng)導(dǎo)者(leader)鹅经,多個(gè)跟隨者(follower)組成的集群。
2)Leader負(fù)責(zé)進(jìn)行投票的發(fā)起和決議怎诫,更新系統(tǒng)狀態(tài)瘾晃。
3)Follower用于接收客戶請(qǐng)求并向客戶端返回結(jié)果,在選舉Leader過程中參與投票幻妓。
4)集群中奇數(shù)臺(tái)服務(wù)器只要有半數(shù)以上節(jié)點(diǎn)存活蹦误,Zookeeper集群就能正常服務(wù)。
5)全局?jǐn)?shù)據(jù)一致:每個(gè)server保存一份相同的數(shù)據(jù)副本,client無論連接到哪個(gè)server强胰,數(shù)據(jù)都是一致的舱沧。
6)更新請(qǐng)求順序進(jìn)行,來自同一個(gè)client的更新請(qǐng)求按其發(fā)送順序依次執(zhí)行偶洋。
7)數(shù)據(jù)更新原子性熟吏,一次數(shù)據(jù)更新要么成功,要么失敗玄窝。
8)實(shí)時(shí)性牵寺,在一定時(shí)間范圍內(nèi),client能讀到最新數(shù)據(jù)恩脂。
1.3 數(shù)據(jù)結(jié)構(gòu)
ZooKeeper數(shù)據(jù)模型的結(jié)構(gòu)與Unix文件系統(tǒng)很類似帽氓,整體上可以看作是一棵樹,每個(gè)節(jié)點(diǎn)稱做一個(gè)ZNode东亦。每一個(gè)ZNode默認(rèn)能夠存儲(chǔ)1MB的元數(shù)據(jù),每個(gè)ZNode都可以通過其路徑唯一標(biāo)識(shí)唬渗。
1.4 應(yīng)用場(chǎng)景
提供的服務(wù)包括:統(tǒng)一命名服務(wù)典阵、統(tǒng)一配置管理、統(tǒng)一集群管理镊逝、服務(wù)器節(jié)點(diǎn)動(dòng)態(tài)上下線壮啊、軟負(fù)載均衡等。
1.4.1 統(tǒng)一命名服務(wù)
1.4.2 統(tǒng)一配置管理
1撑蒜、分布式環(huán)境下歹啼,配置文件管理和同步是一個(gè)常見問題
一個(gè)集群中,所有節(jié)點(diǎn)的配置信息是一致的座菠,比如hadoop集群
對(duì)配置文件修改后狸眼,希望能夠快速同步到各個(gè)節(jié)點(diǎn)上
2、配置管理可交由ZK實(shí)現(xiàn)
(1)可配置信息寫入ZK上的一個(gè)Znode
(2)各個(gè)節(jié)點(diǎn)監(jiān)聽這個(gè)ZNode
(3)一旦Znode中的數(shù)據(jù)被修改浴滴,ZK將通知各個(gè)節(jié)點(diǎn)
1.4.3 統(tǒng)一集群管理
集群管理結(jié)構(gòu)圖如下所示拓萌。
分布式環(huán)境中,實(shí)時(shí)掌握每個(gè)節(jié)點(diǎn)的狀態(tài)是必要的升略。
可根據(jù)節(jié)點(diǎn)實(shí)時(shí)做出一些調(diào)整
可交由Zk實(shí)現(xiàn)
可將節(jié)點(diǎn)信息寫入ZK上的一個(gè)ZNode
監(jiān)聽這個(gè)Znode可獲取它的實(shí)時(shí)狀態(tài)變化
典型應(yīng)用
HBase中Master狀態(tài)監(jiān)控與選舉
1.4.4 服務(wù)器節(jié)點(diǎn)動(dòng)態(tài)上下線
1.4.5 軟負(fù)載均衡
1.5 下載地址
1)官網(wǎng)首頁:
2)下載截圖
二微王、Zookeeper安裝
2.1 本地模式安裝部署
1)安裝前準(zhǔn)備
(1)安裝jdk
(2)上傳zookeeper到linux系統(tǒng)下
(3)修改tar包權(quán)限
[AncientMing@bigdata111 software] tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module/
(5)配置環(huán)境變量
[root@bigdata111 software]PATH:mv zoo_sample.cfg zoo.cfg
進(jìn)入zoo.cfg文件:vim zoo.cfg
修改dataDir路徑為
dataDir=/opt/module/zookeeper-3.4.10/zkData
在/opt/module/zookeeper-3.4.10/這個(gè)目錄上創(chuàng)建zkData文件夾
[AncientMing@bigdata111 zookeeper-3.4.10] bin/zkServer.sh start
(2)查看進(jìn)程是否啟動(dòng)
[AncientMing@bigdata111 zookeeper-3.4.10] bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: standalone
(4)啟動(dòng)客戶端:
[AncientMing@bigdata111 zookeeper-3.4.10] bin/zkServer.sh stop
2.2 配置參數(shù)解讀
解讀zoo.cfg文件中參數(shù)含義
1)tickTime=2000:通信心跳數(shù)品嚣,Zookeeper服務(wù)器心跳時(shí)間炕倘,單位毫秒
Zookeeper使用的基本時(shí)間,服務(wù)器之間或客戶端與服務(wù)器之間維持心跳的時(shí)間間隔翰撑,也就是每個(gè)tickTime時(shí)間就會(huì)發(fā)送一個(gè)心跳罩旋,時(shí)間單位為毫秒。
它用于心跳機(jī)制,并且設(shè)置最小的session超時(shí)時(shí)間為兩倍心跳時(shí)間瘸恼。(session的最小超時(shí)時(shí)間是2*tickTime)
2)initLimit=10:Leader和Follower初始通信時(shí)限
集群中的follower跟隨者服務(wù)器與leader領(lǐng)導(dǎo)者服務(wù)器之間初始連接時(shí)能容忍的最多心跳數(shù)(tickTime的數(shù)量)劣挫,用它來限定集群中的Zookeeper服務(wù)器連接到Leader的時(shí)限。
投票選舉新leader的初始化時(shí)間
Follower在啟動(dòng)過程中东帅,會(huì)從Leader同步所有最新數(shù)據(jù)压固,然后確定自己能夠?qū)ν夥?wù)的起始狀態(tài)。
Leader允許Follower在initLimit時(shí)間內(nèi)完成這個(gè)工作靠闭。
3)syncLimit=5:Leader和Follower同步通信時(shí)限
集群中Leader與Follower之間的最大響應(yīng)時(shí)間單位帐我,假如響應(yīng)超過syncLimit * tickTime,Leader認(rèn)為Follwer死掉愧膀,從服務(wù)器列表中刪除Follwer拦键。
在運(yùn)行過程中,Leader負(fù)責(zé)與ZK集群中所有機(jī)器進(jìn)行通信檩淋,例如通過一些心跳檢測(cè)機(jī)制芬为,來檢測(cè)機(jī)器的存活狀態(tài)。
如果L發(fā)出心跳包在syncLimit之后蟀悦,還沒有從F那收到響應(yīng)媚朦,那么就認(rèn)為這個(gè)F已經(jīng)不在線了。
4)dataDir:數(shù)據(jù)文件目錄+數(shù)據(jù)持久化路徑
保存內(nèi)存數(shù)據(jù)庫快照信息的位置日戈,如果沒有其他說明询张,更新的事務(wù)日志也保存到數(shù)據(jù)庫。
5)clientPort=2181:客戶端連接端口
監(jiān)聽客戶端連接的端口
三浙炼、Zookeeper內(nèi)部原理
3.1 選舉機(jī)制
Server ID: myid(權(quán)重越大)
Zxid:數(shù)據(jù)ID(先一數(shù)據(jù)低進(jìn)行選擇)
1)半數(shù)機(jī)制(Paxos 協(xié)議):集群中半數(shù)以上機(jī)器存活份氧,集群可用。所以zookeeper適合裝在奇數(shù)臺(tái)機(jī)器上弯屈。
2)Zookeeper雖然在配置文件中并沒有指定master和slave蜗帜。但是,zookeeper工作時(shí)资厉,是有一個(gè)節(jié)點(diǎn)為leader钮糖,其他則為follower,Leader是通過內(nèi)部的選舉機(jī)制臨時(shí)產(chǎn)生的酌住。
3)以一個(gè)簡(jiǎn)單的例子來說明整個(gè)選舉的過程店归。
假設(shè)有五臺(tái)服務(wù)器組成的zookeeper集群,它們的id從1-5酪我,同時(shí)它們都是最新啟動(dòng)的消痛,也就是沒有歷史數(shù)據(jù),在存放數(shù)據(jù)量這一點(diǎn)上都哭,都是一樣的秩伞。假設(shè)這些服務(wù)器依序啟動(dòng)逞带,來看看會(huì)發(fā)生什么。
(1)服務(wù)器1啟動(dòng)纱新,此時(shí)只有它一臺(tái)服務(wù)器啟動(dòng)了展氓,它發(fā)出去的報(bào)沒有任何響應(yīng),所以它的選舉狀態(tài)一直是LOOKING狀態(tài)脸爱。
(2)服務(wù)器2啟動(dòng)遇汞,它與最開始啟動(dòng)的服務(wù)器1進(jìn)行通信,互相交換自己的選舉結(jié)果簿废,由于兩者都沒有歷史數(shù)據(jù)空入,所以id值較大的服務(wù)器2勝出,但是由于沒有達(dá)到超過半數(shù)以上的服務(wù)器都同意選舉它(這個(gè)例子中的半數(shù)以上是3)族檬,所以服務(wù)器1歪赢、2還是繼續(xù)保持LOOKING狀態(tài)。
(3)服務(wù)器3啟動(dòng)单料,根據(jù)前面的理論分析埋凯,服務(wù)器3成為服務(wù)器1、2扫尖、3中的老大白对,而與上面不同的是,此時(shí)有三臺(tái)服務(wù)器選舉了它藏斩,所以它成為了這次選舉的leader躏结。
(4)服務(wù)器4啟動(dòng)却盘,根據(jù)前面的分析狰域,理論上服務(wù)器4應(yīng)該是服務(wù)器1、2黄橘、3兆览、4中最大的,但是由于前面已經(jīng)有半數(shù)以上的服務(wù)器選舉了服務(wù)器3塞关,所以它只能接收當(dāng)小弟的命了抬探。
(5)服務(wù)器5啟動(dòng),同4一樣當(dāng)小弟帆赢。
3.2 節(jié)點(diǎn)類型
1)Znode有兩種類型:
短暫(ephemeral):客戶端和服務(wù)器端斷開連接后小压,創(chuàng)建的節(jié)點(diǎn)自己刪除
持久(persistent):客戶端和服務(wù)器端斷開連接后,創(chuàng)建的節(jié)點(diǎn)不刪除
2)Znode有四種形式的目錄節(jié)點(diǎn)(默認(rèn)是persistent )
(1)持久化目錄節(jié)點(diǎn)(PERSISTENT)(小寫:persistent)
客戶端與zookeeper斷開連接后椰于,該節(jié)點(diǎn)依舊存在怠益。
(2)持久化順序編號(hào)目錄節(jié)點(diǎn)(PERSISTENT_SEQUENTIAL)
(小寫:persistent_sequential)
客戶端與zookeeper斷開連接后,該節(jié)點(diǎn)依舊存在瘾婿,只是Zookeeper給該節(jié)點(diǎn)名稱進(jìn)行順序編號(hào)蜻牢。
(3)臨時(shí)目錄節(jié)點(diǎn)(EPHEMERAL)(ephemeral)
客戶端與zookeeper斷開連接后烤咧,該節(jié)點(diǎn)被刪除。
(4)臨時(shí)順序編號(hào)目錄節(jié)點(diǎn)(EPHEMERAL_SEQUENTIAL)(ephemeral_sequential)
客戶端與zookeeper斷開連接后抢呆,該節(jié)點(diǎn)被刪除煮嫌,只是Zookeeper給該節(jié)點(diǎn)名稱進(jìn)行順序編號(hào)反砌。
3)創(chuàng)建znode時(shí)設(shè)置順序標(biāo)識(shí)寸认,znode名稱后會(huì)附加一個(gè)值初肉,順序號(hào)是一個(gè)單調(diào)遞增的計(jì)數(shù)器择卦,由父節(jié)點(diǎn)維護(hù)
4)在分布式系統(tǒng)中蠢莺,順序號(hào)可以被用于為所有的事件進(jìn)行全局排序宁玫,這樣客戶端可以通過順序號(hào)推斷事件的順序
3.3 stat結(jié)構(gòu)體
1)czxid- 引起這個(gè)znode創(chuàng)建的zxid丛肮,創(chuàng)建節(jié)點(diǎn)的事務(wù)的zxid
每次修改ZooKeeper狀態(tài)都會(huì)收到一個(gè)zxid形式的時(shí)間戳洲守,也就是ZooKeeper事務(wù)ID轩娶。
事務(wù)ID是ZooKeeper中所有修改總的次序儿奶。每個(gè)修改都有唯一的zxid,如果zxid1小于zxid2鳄抒,那么zxid1在zxid2之前發(fā)生闯捎。
2)ctime - znode被創(chuàng)建的毫秒數(shù)(從1970年開始)
3)mzxid - znode最后更新的zxid
4)mtime - znode最后修改的毫秒數(shù)(從1970年開始)
5)pZxid-znode最后更新的子節(jié)點(diǎn)zxid
6)cversion - znode子節(jié)點(diǎn)變化號(hào),znode子節(jié)點(diǎn)修改次數(shù)
7)dataversion - znode數(shù)據(jù)變化號(hào)
8)aclVersion - znode訪問控制列表的變化號(hào)
9)ephemeralOwner- 如果是臨時(shí)節(jié)點(diǎn)许溅,這個(gè)是znode擁有者的session id瓤鼻。如果不是臨時(shí)節(jié)點(diǎn)則是0。
10)dataLength- znode的數(shù)據(jù)長(zhǎng)度
11)numChildren - znode子節(jié)點(diǎn)數(shù)量
0.4 監(jiān)聽器原理
監(jiān)聽原理詳解:
首先要有一個(gè)main()線程
在main線程中創(chuàng)建ZK客戶端贤重,這是會(huì)創(chuàng)建兩個(gè)線程茬祷,一個(gè)負(fù)責(zé)網(wǎng)絡(luò)連接通信(connect),一個(gè)負(fù)責(zé)監(jiān)聽(listener)
通過connect線程將注冊(cè)的監(jiān)聽事件發(fā)送給ZK
在ZK的注冊(cè)監(jiān)聽器列表中將注冊(cè)的監(jiān)聽事件添加到列表中
ZK監(jiān)聽到有數(shù)據(jù)或路徑發(fā)生變化時(shí),就會(huì)將這個(gè)消息發(fā)送給listener線程
Listener線程內(nèi)部調(diào)用process()方法
常見的監(jiān)聽
監(jiān)聽節(jié)點(diǎn)數(shù)據(jù)的變化
Get path [watch]
監(jiān)聽子節(jié)點(diǎn)增減的變化
Ls path [watch]
3.5 寫數(shù)據(jù)流程
四并蝗、Zookeeper實(shí)戰(zhàn)
4.1 分布式安裝部署
0)集群規(guī)劃
在bigdata111祭犯、bigdata112和bigdata113三個(gè)節(jié)點(diǎn)上部署Zookeeper。
1)解壓安裝
(1)解壓zookeeper安裝包到/opt/module/目錄下
[AncientMing@bigdata111 software]$ tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module/
(2)在/opt/module/zookeeper-3.4.10/這個(gè)目錄下創(chuàng)建zkData
mkdir -p zkData
(3)重命名/opt/module/zookeeper-3.4.10/conf這個(gè)目錄下的zoo_sample.cfg為zoo.cfg
mv zoo_sample.cfg zoo.cfg
2)配置zoo.cfg文件
(1)具體配置
dataDir=/opt/module/zookeeper-3.4.10/zkData
增加如下配置
#######################cluster##########################
server.1=bigdata111:2888:3888
server.2=bigdata112:2888:3888
server.3=bigdata113:2888:3888
(2)配置參數(shù)解讀
Server.A=B:C:D滚停。
A是一個(gè)數(shù)字沃粗,表示這個(gè)是第幾號(hào)服務(wù)器;
B是這個(gè)服務(wù)器的ip地址键畴;
C是這個(gè)服務(wù)器與集群中的Leader服務(wù)器交換信息的端口最盅;
D是萬一集群中的Leader服務(wù)器掛了,需要一個(gè)端口來重新進(jìn)行選舉起惕,選出一個(gè)新的Leader涡贱,而這個(gè)端口就是用來執(zhí)行選舉時(shí)服務(wù)器相互通信的端口。
集群模式下配置一個(gè)文件myid惹想,這個(gè)文件在dataDir目錄下问词,這個(gè)文件里面有一個(gè)數(shù)據(jù)就是A的值,Zookeeper啟動(dòng)時(shí)讀取此文件勺馆,拿到里面的數(shù)據(jù)與zoo.cfg里面的配置信息比較從而判斷到底是哪個(gè)server戏售。
3)集群操作
(1)在/opt/module/zookeeper-3.4.10/zkData目錄下創(chuàng)建一個(gè)myid的文件
touch myid
添加myid文件侨核,注意一定要在linux里面創(chuàng)建,在notepad++里面很可能亂碼
(2)編輯myid文件
vi myid
在文件中添加與server對(duì)應(yīng)的編號(hào):如2
(3)拷貝配置好的zookeeper到其他機(jī)器上
scp -r zookeeper-3.4.10/ root@bigdata112.AncientMing.com:/opt/app/
scp -r zookeeper-3.4.10/ root@bigdata113.AncientMing.com:/opt/app/
并分別修改myid文件中內(nèi)容為3灌灾、4
(4)分別啟動(dòng)zookeeper
[root@bigdata111 zookeeper-3.4.10]# bin/zkServer.sh start
[root@bigdata112 zookeeper-3.4.10]# bin/zkServer.sh start
[root@bigdata113 zookeeper-3.4.10]# bin/zkServer.sh start
(5)查看狀態(tài)
[root@bigdata111 zookeeper-3.4.10]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: follower
[root@bigdata112 zookeeper-3.4.10]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: leader
[root@bigdata113 zookeeper-3.4.5]# bin/zkServer.sh status
JMX enabled by default
Using config: /opt/module/zookeeper-3.4.10/bin/../conf/zoo.cfg
Mode: follower
4.2 客戶端命令行操作
1)啟動(dòng)客戶端
[AncientMing@bigdata112 zookeeper-3.4.10] bin/zkCli.sh
(3)再次查看根目錄下短暫節(jié)點(diǎn)已經(jīng)刪除
[zk: localhost:2181(CONNECTED) 0] ls /
[app1, zookeeper]
8)創(chuàng)建帶序號(hào)的節(jié)點(diǎn)
(1)先創(chuàng)建一個(gè)普通的根節(jié)點(diǎn)app2
[zk: localhost:2181(CONNECTED) 11] create /app2 "app2"
(2)創(chuàng)建帶序號(hào)的節(jié)點(diǎn)
[zk: localhost:2181(CONNECTED) 13] create -s /app2/aa 888
Created /app2/aa0000000000
[zk: localhost:2181(CONNECTED) 14] create -s /app2/bb 888
Created /app2/bb0000000001
[zk: localhost:2181(CONNECTED) 15] create -s /app2/cc 888
Created /app2/cc0000000002
如果原節(jié)點(diǎn)下有1個(gè)節(jié)點(diǎn)搓译,則再排序時(shí)從1開始,以此類推锋喜。
[zk: localhost:2181(CONNECTED) 16] create -s /app1/aa 888
Created /app1/aa0000000001
9)修改節(jié)點(diǎn)數(shù)據(jù)值
[zk: localhost:2181(CONNECTED) 2] set /app1 999
10)節(jié)點(diǎn)的值變化監(jiān)聽
(1)在104主機(jī)上注冊(cè)監(jiān)聽/app1節(jié)點(diǎn)數(shù)據(jù)變化
[zk: localhost:2181(CONNECTED) 26] get /app1 watch
(2)在103主機(jī)上修改/app1節(jié)點(diǎn)的數(shù)據(jù)
[zk: localhost:2181(CONNECTED) 5] set /app1 777
(3)觀察104主機(jī)收到數(shù)據(jù)變化的監(jiān)聽
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/app1
11)節(jié)點(diǎn)的子節(jié)點(diǎn)變化監(jiān)聽(路徑變化)
(1)在104主機(jī)上注冊(cè)監(jiān)聽/app1節(jié)點(diǎn)的子節(jié)點(diǎn)變化
[zk: localhost:2181(CONNECTED) 1] ls /app1 watch
[aa0000000001, server101]
(2)在103主機(jī)/app1節(jié)點(diǎn)上創(chuàng)建子節(jié)點(diǎn)
[zk: localhost:2181(CONNECTED) 6] create /app1/bb 666
Created /app1/bb
(3)觀察104主機(jī)收到子節(jié)點(diǎn)變化的監(jiān)聽
WATCHER::
WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/app1
12)刪除節(jié)點(diǎn)
[zk: localhost:2181(CONNECTED) 4] delete /app1/bb
13)遞歸刪除節(jié)點(diǎn)
[zk: localhost:2181(CONNECTED) 7] rmr /app2
14)查看節(jié)點(diǎn)狀態(tài)
[zk: localhost:2181(CONNECTED) 12] stat /app1
cZxid = 0x20000000a
ctime = Mon Jul 17 16:08:35 CST 2017
mZxid = 0x200000018
mtime = Mon Jul 17 16:54:38 CST 2017
pZxid = 0x20000001c
cversion = 4
dataVersion = 2
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 2
4.3 API應(yīng)用
4.3.1 IDEA環(huán)境搭建
1)創(chuàng)建一個(gè)工程
Pom.xml
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
</dependencies>
4.3.2 創(chuàng)建ZooKeeper客戶端
private static String connectString = "bigdata111:2181,bigdata112:2181,bigdata113:2181";
private static int sessionTimeout = 2000;
private ZooKeeper zkClient = null;
@Before
public void init() throws Exception {
zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
// 收到事件通知后的回調(diào)函數(shù)(用戶的業(yè)務(wù)邏輯)
System.out.println(event.getType() + "--" + event.getPath());
// 再次啟動(dòng)監(jiān)聽
try {
zkClient.getChildren("/", true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
4.3.3 創(chuàng)建子節(jié)點(diǎn)
// 創(chuàng)建子節(jié)點(diǎn)
@Test
public void create() throws Exception {
// 數(shù)據(jù)的增刪改查
// 參數(shù)1:要?jiǎng)?chuàng)建的節(jié)點(diǎn)的路徑些己; 參數(shù)2:節(jié)點(diǎn)數(shù)據(jù) ; 參數(shù)3:節(jié)點(diǎn)權(quán)限 嘿般;參數(shù)4:節(jié)點(diǎn)的類型
String nodeCreated = zkClient.create("/eclipse", "hello zk".getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
}
4.3.4 獲取子節(jié)點(diǎn)并監(jiān)聽
// 獲取子節(jié)點(diǎn)
@Test
public void getChildren() throws Exception {
List<String> children = zkClient.getChildren("/", true);
for (String child : children) {
System.out.println(child);
}
// 延時(shí)阻塞
Thread.sleep(Long.MAX_VALUE);
}
4.3.5 判斷znode是否存在
// 判斷znode是否存在
@Test
public void exist() throws Exception {
Stat stat = zkClient.exists("/eclipse", false);
System.out.println(stat == null ? "not exist" : "exist");
}
4.4 案例實(shí)戰(zhàn) 分布式秒殺
Zk所需要的Pom依賴
重點(diǎn)配置哦
<!-- zookeeper所需依賴 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-client</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>16.0.1</version>
</dependency>
TestDistributedLock
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
public class TestDistributedLock {
//定義共享資源
private static int count = 10;
private static void printCountNumber() {
System.out.println("***********" + Thread.currentThread().getName() + "**********");
System.out.println("當(dāng)前值:" + count);
count--;
//睡2秒
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("***********" + Thread.currentThread().getName() + "**********");
}
public static void main(String[] args) {
//定義客戶端重試的策略
RetryPolicy policy = new ExponentialBackoffRetry(1000, //每次等待的時(shí)間
10); //最大重試的次數(shù)
//定義ZK的一個(gè)客戶端
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString("bigdata111:2181")
.retryPolicy(policy)
.build();
//在ZK生成鎖 ---> 就是ZK的目錄
client.start();
final InterProcessMutex lock = new InterProcessMutex(client, "/mylock");
// 啟動(dòng)10個(gè)線程去訪問共享資源
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
public void run() {
try {
//請(qǐng)求得到鎖
lock.acquire();
//訪問共享資源
printCountNumber();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
//釋放鎖
try {
lock.release();
} catch (Exception e) {
e.printStackTrace();
}
}
可以敲一敲段标。
核心
下載壓縮包到Linux,然后解壓炉奴。
cd 到解壓的目錄
重點(diǎn)
cd conf/
我們要把zoo_sample.cfg改為zoo.cfg
mv zoo_sample.cfg zoo.cfg
然后修改配置文件
重要目錄:
cd bin/
其中zkCli.sh是啟動(dòng)客戶端
zkServer.sh是啟動(dòng)和停止
zkServer.sh start
zkServer.sh stop