連鎖酒店網(wǎng)站建設(shè)網(wǎng)站優(yōu)化推廣方案
Zookeeper概述
Zookeeper 是一個開源的分布式的,為分布式框架提供協(xié)調(diào)服務(wù)的 Apache 項目
工作機制
Zookeeper從設(shè)計模式角度來理解:是一個基于觀察者模式設(shè)計的分布式服務(wù)管理框架,它負責(zé)存儲和管理大家都關(guān)心的數(shù)據(jù),然后接受觀察者的注 冊,一旦這些數(shù)據(jù)的狀態(tài)發(fā)生變化,Zookeeper就 將負責(zé)通知已經(jīng)在Zookeeper上注冊的那些觀察者做出相應(yīng)的反應(yīng)
Zookeeper=文件系統(tǒng)+通知機制
其主要功能為:數(shù)據(jù)存儲+通知更新
以服務(wù)器上下線為例:
1.服務(wù)端啟動,到zookeeper集群中注冊信息
2.客戶端從zookeeper集群中獲取到當(dāng)前服務(wù)器的列表并注冊監(jiān)聽
3.服務(wù)器節(jié)點下線
4.zookeeper集群將服務(wù)器節(jié)點下線事件通知到客戶端
5.客戶端重新獲取服務(wù)器列表,并注冊監(jiān)聽
特點
1)Zookeeper是一個領(lǐng)導(dǎo)者(Leader),多個跟隨者(Follower)組成的集群
2)集群中只要有半數(shù)以上節(jié)點存活,Zookeeper集群就能正常服務(wù)。所 以Zookeeper適合安裝奇數(shù)臺服務(wù)器
偶數(shù)臺服務(wù)器并不能提升zookeeper的性能
3)全局數(shù)據(jù)一致:每個Server保存一份相同的數(shù)據(jù)副本,Client無論連接到哪個Server,數(shù)據(jù)都是一致的
4)更新請求順序執(zhí)行,來自同一個Client的更新請求按其發(fā)送順序依次執(zhí)行
5)數(shù)據(jù)更新原子性,一次數(shù)據(jù)更新要么成功,要么失敗
6)實時性,在一定時間范圍內(nèi),Client能讀到最新數(shù)據(jù)
數(shù)據(jù)結(jié)構(gòu)
ZooKeeper 數(shù)據(jù)模型的結(jié)構(gòu)與 Unix 文件系統(tǒng)很類似,整體上可以看作是一棵樹,每個節(jié)點稱做一個 ZNode。每一個 ZNode 默認能夠存儲 1MB 的數(shù)據(jù),每個 ZNode 都可以通過其路徑唯一標(biāo)識
ZNode結(jié)構(gòu)決定了ZooKeeper只適合存儲一些簡單的配置文件,不適合存儲海量數(shù)據(jù)
應(yīng)用場景
Zookeeper提供的服務(wù)包括:統(tǒng)一命名服務(wù)、統(tǒng)一配置管理、統(tǒng)一集群管理、服務(wù)器節(jié)點動態(tài)上下線、軟負載均衡等
統(tǒng)一命名服務(wù)
統(tǒng)一配置管理
分布式環(huán)境下經(jīng)常有各個節(jié)點配置信息一致的要求,因此對配置文件修改后,希望能快速同步到各個節(jié)點上;
zookeeper進行統(tǒng)一配置管理的簡單流程:
(1)可將配置信息寫入ZooKeeper上的一個Znode
(2)各個客戶端服務(wù)器監(jiān)聽這個Znode
(3)一旦Znode中的數(shù)據(jù)被修改,ZooKeeper將通知各個客戶端服務(wù)器
統(tǒng)一集群管理
將節(jié)點信息寫入zookeeper的ZNode中,然后監(jiān)聽該ZNode即可獲取集群節(jié)點的實時狀態(tài)變化;
服務(wù)器動態(tài)上下線
客戶端能實時洞察到服務(wù)器上下線的變化:
1.服務(wù)端啟動,到zookeeper集群中注冊信息
2.客戶端從zookeeper集群中獲取到當(dāng)前服務(wù)器的列表并注冊監(jiān)聽
3.服務(wù)器節(jié)點下線
4.zookeeper集群將服務(wù)器節(jié)點下線事件通知到客戶端
5.客戶端重新獲取服務(wù)器列表,并注冊監(jiān)聽
軟負載均衡
在Zookeeper中記錄每臺服務(wù)器的訪問數(shù),讓訪問數(shù)最少的服務(wù)器去處理最新的客戶端請求
Zookeeper集群搭建
安裝包下載
官網(wǎng)地址:Apache ZooKeeper
進入下載界面:
選擇tar包:
安裝流程
集群一共使用在三臺服務(wù)器上部署zookeeper,服務(wù)器名稱分別為hadoop102-hadoop104
1.上傳安裝包到服務(wù)器上,使用tar -zxvf
進行解壓到/opt/module/
路徑下(自定義的路徑)
2.將解壓后的apache-zookeeper-3.5.7-bin
重命名為zookeeper-3.5.7
3.配置服務(wù)器編號:
在/opt/module/zookeeper-3.5.7/
這個目錄下創(chuàng)建 zkData
然后在該目錄下創(chuàng)建一個名為myid的文件
文件名稱是固定的,因為源碼中讀取的文件名稱就是myid
然后在文件中添加與server 對應(yīng)的編號(三臺服務(wù)器的編號分別為2、3、4)
4.配置zoo.cfg文件:
重命名/opt/module/zookeeper-3.5.7/conf
這個目錄下的 zoo_sample.cfg 為 zoo.cfg
然后打開 zoo.cfg:
①修改數(shù)據(jù)存儲路徑dataDir:dataDir=/opt/module/zookeeper-3.5.7/zkData
②增加集群配置:
server.2=hadoop102:2888:3888
server.3=hadoop103:2888:3888
server.4=hadoop104:2888:3888
配置參數(shù)格式:
server.A=B:C:D
A 是一個數(shù)字,表示這個是第幾號服務(wù)器;集群模式下配置一個文件 myid,這個文件在 dataDir 目錄下,這個文件里面有一個數(shù)據(jù)就是 A 的值,Zookeeper 啟動時讀取此文件,拿到里面的數(shù)據(jù)與 zoo.cfg 里面的配置信息比較從而判斷到底是哪個 server
B 是這個服務(wù)器的地址;
C 是這個服務(wù)器 Follower 與集群中的 Leader 服務(wù)器交換信息的端口(2888);
D 是萬一集群中的 Leader 服務(wù)器掛了,需要一個端口來重新進行選舉,選出一個新的Leader,而這個端口就是用來執(zhí)行選舉時服務(wù)器相互通信的端口(3888)
5.將myid及zoo.cfg的配置分發(fā)到所有服務(wù)器上(注意服務(wù)器編號要修改)
集群啟動
進入zookeeper路徑下:
啟動:bin/zkServer.sh start
停止:bin/zkServer.sh stop
查看狀態(tài):bin/zkServer.sh status
(附)zoo.cfg配置參數(shù)解讀
1.tickTime = 2000:通信心跳時間,Zookeeper服務(wù)器與客戶端通信心跳時間,單位為毫秒
2.initLimit = 10:LF初始通信時限(Leader和Follower初始連接時能容忍的最多心跳數(shù)(tickTime的數(shù)量))
當(dāng)前配置下,tickTime = 2000,initLimit = 10,則如果Leader和Follower20s內(nèi)未建立連接,就認為通信失敗
3.syncLimit = 5:LF同步通信時限
Leader和Follower之間通信時間如果超過
syncLimit * tickTime
(也就是10s),Leader認為Follwer掛掉,從服務(wù)器列表中刪除Follwer
4.dataDir:Zookeeper中數(shù)據(jù)存儲的路徑
![]()
不建議使用默認的tmp目錄,可能會被linux定期刪除
5.clientPort = 2181:客戶端連接端口,通常不做修改
?
(附)集群啟停腳本
在/home/username/bin
(如/home/why/bin)路徑下新建zk.sh文件:
#!/bin/bash
case $1 in
"start"){
for i in hadoop102 hadoop103 hadoop104
doecho ---------- zookeeper $i 啟動 ------------
ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh start"
done
};;"stop"){
for i in hadoop102 hadoop103 hadoop104
doecho ---------- zookeeper $i 停止 ------------
ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh stop"
done
};;"status"){
for i in hadoop102 hadoop103 hadoop104
doecho ---------- zookeeper $i 狀態(tài) ------------
ssh $i "/opt/module/zookeeper-3.5.7/bin/zkServer.sh status"
done
};;esac
即將
bin/zkServer.sh start
、bin/zkServer.sh stop
、bin/zkServer.sh status
等指令封裝起來添加權(quán)限:
chmod u+x zk.sh
這樣就可以通過
zk.sh start
、zk.sh stop
進行集群的啟停了
Zookeeper選舉機制
第一次啟動
假設(shè)集群中一共有5臺服務(wù)器:
(1)服務(wù)器1啟動,發(fā)起一次選舉。服務(wù)器1投自己一票。此時服務(wù)器1票數(shù)一票,不夠半數(shù)以上(3票),選舉無法完成,服務(wù)器1狀態(tài)保持為LOOKING;
(2)服務(wù)器2啟動,再發(fā)起一次選舉。服務(wù)器1和2分別投自己一票并交換選票信息:此時服務(wù)器1發(fā)現(xiàn)服務(wù)器2的myid比自己目前投票推舉的(服務(wù)器1)大,更改選票為推舉服務(wù)器2。此時服務(wù)器1票數(shù)0票,服務(wù)器2票數(shù)2票,沒有半數(shù)以上結(jié)果,選舉無法完成,服務(wù)器1,2狀態(tài)保持LOOKING
根據(jù)myid進行投票選擇
(3)服務(wù)器3啟動,發(fā)起一次選舉。此時服務(wù)器1和2都會更改選票為服務(wù)器3。此次投票結(jié)果:服務(wù)器1為0票,服務(wù)器2為0票,服務(wù)器3為3票。此時服務(wù)器3的票數(shù)已經(jīng)超過半數(shù),服務(wù)器3當(dāng)選Leader。服務(wù)器1,2更改狀態(tài)為FOLLOWING,服務(wù)器3更改狀態(tài)為LEADING;
(4)服務(wù)器4啟動,發(fā)起一次選舉。此時服務(wù)器1,2,3已經(jīng)不是LOOKING狀態(tài),不會更改選票信息。交換選票信息結(jié)果:服務(wù)器3為3票,服務(wù)器4為1票。此時服務(wù)器4服從多數(shù),更改選票信息為服務(wù)器3,并更改狀態(tài)為FOLLOWING;
(5)服務(wù)器5啟動,與服務(wù)器4相同
集群中產(chǎn)生leader之后不再繼續(xù)選舉
非第一次啟動
當(dāng)ZooKeeper集群中的一臺服務(wù)器出現(xiàn)以下兩種情況之一時,就會開始進入Leader選舉:
- 服務(wù)器初始化啟動
- 服務(wù)器運行期間無法和Leader保持連接
而當(dāng)一臺機器進入Leader選舉流程時,當(dāng)前集群也可能會處于以下兩種狀態(tài):
- 集群中本來就已經(jīng)存在一個Leader。
對于第一種已經(jīng)存在Leader的情況,機器試圖去選舉Leader時,會被告知當(dāng)前服務(wù)器的Leader信息,對于該機器來說,僅僅需要和Leader機器建立連接,并進行狀態(tài)同步即可
- 集群中確實不存在Leader
此時的選舉規(guī)則如下:
假設(shè)ZooKeeper由5臺服務(wù)器組成,SID分別為1、2、3、4、5,ZXID分別為8、8、8、7、7,并且此時SID為3的服務(wù)器是Leader。某一時刻,3和5服務(wù)器出現(xiàn)故障,因此開始進行Leader選舉
SID為1、2、4的機器投票情況:(EPOCH,ZXID,SID )
(1,8,1) (1,8,2) (1,7,4)
選舉Leader規(guī)則:
①EPOCH大的直接勝出
②EPOCH相同,事務(wù)id大的勝出
③事務(wù)id相同,服務(wù)器id大的勝出
參數(shù)說明:
● SID:服務(wù)器ID。用來唯一標(biāo)識一臺ZooKeeper集群中的機器,每臺機器不能重復(fù),和myid一致。
● ZXID:事務(wù)ID。ZXID是一個事務(wù)ID,用來標(biāo)識一次服務(wù)器狀態(tài)的變更。在某一時刻,集群中的每臺機器的ZXID值不一定完全一致,這和ZooKeeper服務(wù)器對于客戶端“更新請求”的處理邏輯有關(guān)。
● Epoch:每個Leader任期的代號。沒有Leader時同一輪投票過程中的邏輯時鐘值是相同的。每投完一次票這個數(shù)據(jù)就會增加
Zookeeper 命令行操作
命令行語法
命令基本語法 | 功能描述 |
help | 顯示所有操作命令 |
ls path | 使用 ls 命令來查看當(dāng)前 znode 的子節(jié)點 [可監(jiān)聽] -w 監(jiān)聽子節(jié)點變化 -s 附加次級信息 |
create | 普通創(chuàng)建znode節(jié)點 -s 含有序列 -e 臨時(重啟或者超時消失) |
get path | 獲得節(jié)點的值 [可監(jiān)聽] -w 監(jiān)聽節(jié)點內(nèi)容變化 -s 附加次級信息 |
set | 設(shè)置節(jié)點的具體值 |
stat | 查看節(jié)點狀態(tài) |
delete | 刪除節(jié)點 |
deleteall | 遞歸刪除節(jié)點 |
命令行實操
首先啟動zookeeper集群
然后進入zookeeper安裝路徑下,啟動客戶端:
bin/zkCli.sh -server hadoop102:2181
help
使用help查看幫助:
節(jié)點數(shù)據(jù)信息(ls)
ls /
:查看zookeeper中所有的znode節(jié)點
ls -s /
:查看更多節(jié)點信息
(1)czxid:創(chuàng)建節(jié)點的事務(wù) zxid
每次修改 ZooKeeper 狀態(tài)都會產(chǎn)生一個 ZooKeeper 事務(wù) ID。事務(wù) ID 是 ZooKeeper 中所有修改總的次序。每次修改都有唯一的 zxid,如果 zxid1 小于 zxid2,那么 zxid1 在 zxid2 之前發(fā)生
(2)ctime:znode 被創(chuàng)建的毫秒數(shù)(從 1970 年開始)
(3)mzxid:znode 最后更新的事務(wù) zxid
(4)mtime:znode 最后修改的毫秒數(shù)(從 1970 年開始)
(5)pZxid:znode 最后更新的子節(jié)點 zxid
(6)cversion:znode 子節(jié)點變化號,znode 子節(jié)點修改次數(shù)
(7)dataversion:znode 數(shù)據(jù)變化號
(8)aclVersion:znode 訪問控制列表的變化號
(9)ephemeralOwner:如果是臨時節(jié)點,這個是 znode 擁有者的 session id。如果不是臨時節(jié)點則是0
(10)dataLength:znode 的數(shù)據(jù)長度
(11)numChildren:znode 子節(jié)點數(shù)量
注意,使用ls -s /查看的是整個znode樹的根節(jié)點
即是該根節(jié)點下面所有的子節(jié)點,要想查看子節(jié)點的具體信息,使用具體路徑即可;
例如:
ls -s /why
:
節(jié)點類型(create/get/set)?
節(jié)點類型主要分為以下四種:
(1)持久化目錄節(jié)點:客戶端與Zookeeper斷開連接后,該節(jié)點依舊存在
(2)持久化順序編號目錄節(jié)點:客戶端與Zookeeper斷開連接后,該節(jié)點依舊存在,只是Zookeeper給該節(jié)點名稱進行順序編號
(3)臨時目錄節(jié)點:客戶端與Zookeeper斷開連接后,該節(jié)點被刪除
(4)臨時順序編號目錄節(jié)點:客戶端與 Zookeeper 斷開連接后 , 該節(jié)點被刪除 , 只 是Zookeeper給該節(jié)點名稱進行順序編號。
順序編號的含義:
創(chuàng)建znode時設(shè)置順序標(biāo)識,znode名稱后會附加一個值,順序號是一個單調(diào)遞增的計數(shù)器,由父節(jié)點維護在分布式系統(tǒng)中,順序號可以被用于為所有的事件進行全局排序,這樣客戶端可以通過順序號推斷事件的順序
創(chuàng)建普通節(jié)點(永久節(jié)點 + 不帶序號)
1.create /bigdata "bigdata"
:create普通節(jié)點,/bigdata
是路徑,"bigdata"
是節(jié)點值
zookeeper創(chuàng)建節(jié)點時需要賦值
2.create /bigdata/test1 "test1"
查看節(jié)點的值:
get -s /bigdata
get -s /bigdata/test1
創(chuàng)建帶序號的節(jié)點(永久節(jié)點 + 帶序號)
首先創(chuàng)建一個節(jié)點:create /bigdata/test2 "test2"
然后在該節(jié)點下創(chuàng)建帶序號的永久節(jié)點(通過 -s 創(chuàng)建)
如果原來沒有序號節(jié)點,序號從 0 開始依次遞增。如果原節(jié)點下已有 2 個節(jié)點,則再排序時從 2 開始,以此類推
創(chuàng)建短暫節(jié)點
首先創(chuàng)建一個節(jié)點:create /bigdata/test3 "test3"
然后在該節(jié)點下創(chuàng)建短暫節(jié)點(通過 -e 創(chuàng)建):create -e /bigdata/test3/e1 "e1"
可以查看該節(jié)點:
接下來退出客戶端,重啟zookeeper集群,之后重新進入客戶端去查看該節(jié)點:
可以看到該短暫節(jié)點已經(jīng)不存在了;
修改節(jié)點的值
使用set指令:
set /bigdata "bigdata_why"
監(jiān)聽器原理
客戶端注冊監(jiān)聽它關(guān)心的目錄節(jié)點,當(dāng)目錄節(jié)點發(fā)生變化(數(shù)據(jù)改變、節(jié)點刪除、子目錄節(jié)點增加刪除)時,ZooKeeper 會通知客戶端。監(jiān)聽機制保證 ZooKeeper 保存的任何的數(shù)據(jù)的任何改變都能快速的響應(yīng)到監(jiān)聽了該節(jié)點的應(yīng)用程序
工作流程
1)首先要有一個main()線程
2)在main線程中創(chuàng)建Zookeeper客戶端,這時就會創(chuàng)建兩個線程,一個負責(zé)網(wǎng)絡(luò)連接通信(connet),一個負責(zé)監(jiān)聽(listener)
3)通過connect線程將注冊的監(jiān)聽事件發(fā)送給Zookeeper
4)在Zookeeper的注冊監(jiān)聽器列表中將注冊的監(jiān)聽事件添加到列表中
5)Zookeeper監(jiān)聽到有數(shù)據(jù)或路徑變化,就會將這個消息發(fā)送給listener線程
6)listener線程內(nèi)部調(diào)用了process()方法,將變化通知到客戶端
常見的監(jiān)聽
1)監(jiān)聽節(jié)點數(shù)據(jù)的變化:get path [watch]
2)監(jiān)聽子節(jié)點增減的變化:ls path [watch]
節(jié)點的值變化
監(jiān)聽bigdata節(jié)點的變化:get -w /bigdata
可以看到節(jié)點當(dāng)前的值:
在hadoop103上修改節(jié)點的值:
在hadoop102中即可監(jiān)聽到節(jié)點數(shù)據(jù)的變化:
節(jié)點的子節(jié)點變化監(jiān)聽
在hadoop102中:
ls -w /bigdata
:監(jiān)聽bigdata節(jié)點
在hadoop103中新建子節(jié)點:
在hadoop102中即可監(jiān)聽到子節(jié)點的變化
節(jié)點刪除與狀態(tài)查看
刪除節(jié)點:delete /bigdata/test4
遞歸刪除:deleteall /bigdata/test2
可以看到刪除成功
查看節(jié)點狀態(tài):stat /bigdata