088-BigData-16ZooKeeper

上一篇: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í)唬渗。

image.png

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ù)

image.png

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)

image.png

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)控與選舉

image.png

1.4.4 服務(wù)器節(jié)點(diǎn)動(dòng)態(tài)上下線

image.png

1.4.5 軟負(fù)載均衡

image.png

1.5 下載地址

1)官網(wǎng)首頁:

官網(wǎng)首頁

2)下載截圖

image.png
image.png

二微王、Zookeeper安裝

2.1 本地模式安裝部署

1)安裝前準(zhǔn)備

(1)安裝jdk
(2)上傳zookeeper到linux系統(tǒng)下
(3)修改tar包權(quán)限
[AncientMing@bigdata111 software]chmod u+x zookeeper-3.4.10.tar.gz (4)解壓到指定目錄 [AncientMing@bigdata111 software] tar -zxvf zookeeper-3.4.10.tar.gz -C /opt/module/
(5)配置環(huán)境變量
[root@bigdata111 software]vi /etc/profile export ZOOKEEPER_HOME=/opt/module/zookeeper-3.4.10 export PATH=PATH:ZOOKEEPER_HOME/bin 2)配置修改 將/opt/module/zookeeper-3.4.10/conf這個(gè)路徑下的zoo_sample.cfg修改為zoo.cfg; [AncientMing@bigdata111 zookeeper-3.4.10]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]mkdir zkData 3)操作zookeeper (1)啟動(dòng)zookeeper [AncientMing@bigdata111 zookeeper-3.4.10] bin/zkServer.sh start
(2)查看進(jìn)程是否啟動(dòng)
[AncientMing@bigdata111 zookeeper-3.4.10]jps 4020 Jps 4001 QuorumPeerMain (3)查看狀態(tài): [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/zkCli.sh (5)退出客戶端: [zk: localhost:2181(CONNECTED) 0] quit (6)停止zookeeper [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)反砌。

image.png

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]

image.png

3.5 寫數(shù)據(jù)流程

image.png

四并蝗、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 客戶端命令行操作

image.png

1)啟動(dòng)客戶端
[AncientMing@bigdata112 zookeeper-3.4.10]bin/zkCli.sh 2)顯示所有操作命令 [zk: localhost:2181(CONNECTED) 1] help 3)查看當(dāng)前znode中所包含的內(nèi)容 [zk: localhost:2181(CONNECTED) 0] ls / [zookeeper] 4)查看當(dāng)前節(jié)點(diǎn)數(shù)據(jù)并能看到更新次數(shù)等數(shù)據(jù) [zk: localhost:2181(CONNECTED) 1] ls2 / [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 = -1 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 0 numChildren = 1 5)創(chuàng)建普通節(jié)點(diǎn) [zk: localhost:2181(CONNECTED) 2] create /app1 "hello app1" Created /app1 [zk: localhost:2181(CONNECTED) 4] create /app1/server101 "192.168.1.101" Created /app1/server101 6)獲得節(jié)點(diǎn)的值 [zk: localhost:2181(CONNECTED) 6] get /app1 hello app1 cZxid = 0x20000000a ctime = Mon Jul 17 16:08:35 CST 2017 mZxid = 0x20000000a mtime = Mon Jul 17 16:08:35 CST 2017 pZxid = 0x20000000b cversion = 1 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 10 numChildren = 1 [zk: localhost:2181(CONNECTED) 8] get /app1/server101 192.168.1.101 cZxid = 0x20000000b ctime = Mon Jul 17 16:11:04 CST 2017 mZxid = 0x20000000b mtime = Mon Jul 17 16:11:04 CST 2017 pZxid = 0x20000000b cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 13 numChildren = 0 7)創(chuàng)建短暫節(jié)點(diǎn) [zk: localhost:2181(CONNECTED) 9] create -e /app-emphemeral 8888 (1)在當(dāng)前客戶端是能查看到的 [zk: localhost:2181(CONNECTED) 10] ls / [app1, app-emphemeral, zookeeper] (2)退出當(dāng)前客戶端然后再重啟客戶端 [zk: localhost:2181(CONNECTED) 12] quit [AncientMing@bigdata113 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 到解壓的目錄

image.png

重點(diǎn)

cd conf/
image.png
image.png

我們要把zoo_sample.cfg改為zoo.cfg

mv zoo_sample.cfg zoo.cfg
image.png

然后修改配置文件

重要目錄:

cd bin/
image.png

其中zkCli.sh是啟動(dòng)客戶端

zkServer.sh是啟動(dòng)和停止

zkServer.sh start
zkServer.sh stop

下一篇:089-BigData-17ZooKeeper秒殺和hadoop高可用

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逼庞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子瞻赶,更是在濱河造成了極大的恐慌赛糟,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砸逊,死亡現(xiàn)場(chǎng)離奇詭異璧南,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)师逸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門司倚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人篓像,你說我怎么就攤上這事动知。” “怎么了遗淳?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵拍柒,是天一觀的道長(zhǎng)心傀。 經(jīng)常有香客問我屈暗,道長(zhǎng),這世上最難降的妖魔是什么脂男? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任养叛,我火速辦了婚禮,結(jié)果婚禮上宰翅,老公的妹妹穿的比我還像新娘弃甥。我一直安慰自己,他們只是感情好汁讼,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布淆攻。 她就那樣靜靜地躺著阔墩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪瓶珊。 梳的紋絲不亂的頭發(fā)上啸箫,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音伞芹,去河邊找鬼忘苛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛唱较,可吹牛的內(nèi)容都是我干的扎唾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼南缓,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼胸遇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起汉形,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤狐榔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后获雕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體薄腻,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年届案,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了庵楷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡楣颠,死狀恐怖尽纽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情童漩,我是刑警寧澤弄贿,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站矫膨,受9級(jí)特大地震影響差凹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜侧馅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一危尿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧馁痴,春花似錦谊娇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赠堵。三九已至,卻和暖如春法褥,著一層夾襖步出監(jiān)牢的瞬間顾腊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工挖胃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杂靶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓酱鸭,卻偏偏與公主長(zhǎng)得像吗垮,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子凹髓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容