圖解ZooKeeper,注冊(cè)中心、負(fù)載均衡、通知機(jī)制、集群、寫(xiě)原理,一網(wǎng)打盡!
一、ZooKeeper是什么?
1、開(kāi)源的分布式協(xié)調(diào)服務(wù)
使用分布式系統(tǒng)就無(wú)法避免對(duì)節(jié)點(diǎn)管理的問(wèn)題(需要實(shí)時(shí)感知節(jié)點(diǎn)的狀態(tài)、對(duì)節(jié)點(diǎn)進(jìn)行統(tǒng)一管理等等),而由于這些問(wèn)題處理起來(lái)可能相對(duì)麻煩和提高了系統(tǒng)的復(fù)雜性,ZooKeeper作為一個(gè)能夠通用解決這些問(wèn)題的中間件就應(yīng)運(yùn)而生了。
2、從設(shè)計(jì)模式角度來(lái)理解
ZooKeeper是一個(gè)基于觀察者模式設(shè)計(jì)的分布式服務(wù)管理框架,它負(fù)責(zé)存儲(chǔ)和管理大家都關(guān)心的數(shù)據(jù),一旦這些數(shù)據(jù)的狀態(tài)發(fā)生變化,Zookeeper 就將負(fù)責(zé)通知已經(jīng)在Zookeeper上注冊(cè)的那些觀察者做出相應(yīng)的反應(yīng)。
3、實(shí)現(xiàn)原理
zookeeper = 文件系統(tǒng) + 通知機(jī)制。
二、Zookeeper的作用
1、統(tǒng)一配置管理
比如現(xiàn)在有A.yml,B.yml,C.yml配置文件,里面有一些公共的配置,但是如果后期對(duì)這些公共的配置進(jìn)行修改,就需要修改每一個(gè)文件,還要重啟服務(wù)器,比較麻煩。
現(xiàn)在將這些公共配置信息放到Zookeeper中,修改Zookeeper的信息,會(huì)通知A,B,C配置文件,很方便。
2、統(tǒng)一命名服務(wù)
這個(gè)的理解其實(shí)跟域名一樣,在某一個(gè)節(jié)點(diǎn)下放一些ip地址,我現(xiàn)在只需要訪問(wèn)Zookeeper的一個(gè)Znode節(jié)點(diǎn)就可以獲取這些ip地址。
3、同一集群管理
分布式集群中狀態(tài)的監(jiān)控和管理,使用Zookeeper來(lái)存儲(chǔ)。
4、分布式協(xié)調(diào)
這個(gè)是我們最常用的,比如把多個(gè)服務(wù)提供者的信息放在某個(gè)節(jié)點(diǎn)上,服務(wù)的消費(fèi)者就可以通過(guò)ZK調(diào)用。
服務(wù)節(jié)點(diǎn)動(dòng)態(tài)上下線
如果提供者宕機(jī),就會(huì)刪除在Zookeeper的節(jié)點(diǎn),然后Zookeeper通知給消費(fèi)者。
5、軟負(fù)載均衡
6、動(dòng)態(tài)選舉Master
Zookeeper會(huì)每次選舉最小編號(hào)的作為Master,如果Master掛了,自然對(duì)應(yīng)的Znode節(jié)點(diǎn)就會(huì)刪除。然后讓新的最小編號(hào)作為Master,這樣就可以實(shí)現(xiàn)動(dòng)態(tài)選舉的功能了。
三、Zookeeper文件系統(tǒng)
ZooKeeper的數(shù)據(jù)結(jié)構(gòu),跟Unix文件系統(tǒng)非常類(lèi)似,可以看做是一顆樹(shù),每個(gè)節(jié)點(diǎn)叫做Znode,每一個(gè)Znode只能存1MB數(shù)據(jù),數(shù)據(jù)只是配置信息。
每一個(gè)節(jié)點(diǎn)可以通過(guò)路徑來(lái)標(biāo)識(shí),結(jié)構(gòu)圖如下:
節(jié)點(diǎn)主要有4種類(lèi)型:
1、臨時(shí)目錄節(jié)點(diǎn):客戶端與Zookeeper斷開(kāi)連接后,該節(jié)點(diǎn)被刪除。
2、臨時(shí)順序編號(hào)目錄節(jié)點(diǎn):基本特性同臨時(shí)節(jié)點(diǎn),只是增加了順序?qū)傩裕?jié)點(diǎn)名后邊會(huì)追加一個(gè)由父節(jié)點(diǎn)維護(hù)的自增整型數(shù)字。
3、持久化目錄節(jié)點(diǎn):客戶端與Zookeeper斷開(kāi)連接后,該節(jié)點(diǎn)依舊存在。
4、持久化順序編號(hào)目錄節(jié)點(diǎn):基本特性同持久節(jié)點(diǎn),只是增加了順序?qū)傩裕?jié)點(diǎn)名后邊會(huì)追加一個(gè)由父節(jié)點(diǎn)維護(hù)的自增整型數(shù)字。
四、通知機(jī)制 (監(jiān)聽(tīng)機(jī)制)
Zookeeper可以提供分布式數(shù)據(jù)的發(fā)布/訂閱功能,依賴(lài)的就是Wather監(jiān)聽(tīng)機(jī)制。
客戶端可以向服務(wù)端注冊(cè)Wather監(jiān)聽(tīng),服務(wù)端的指定事件觸發(fā)之后,就會(huì)向客戶端發(fā)送一個(gè)事件通知。
1、具體步如下:
(1)客戶端向服務(wù)端注冊(cè)Wather監(jiān)聽(tīng)。
(2)保存Wather對(duì)象到客戶端本地的WatherManager中。
(3)服務(wù)端Wather事件觸發(fā)后,客戶端收到服務(wù)端通知,從WatherManager(watcher管理器)中取出對(duì)應(yīng)Wather對(duì)象執(zhí)行回調(diào)邏輯。
2、主要監(jiān)聽(tīng)2方面內(nèi)容:
(1)監(jiān)聽(tīng)Znode節(jié)點(diǎn)的數(shù)據(jù)變化:就是那個(gè)節(jié)點(diǎn)信息更新了。
(2)監(jiān)聽(tīng)子節(jié)點(diǎn)的增減變化:就是增加了一個(gè)Znode或者刪除了一個(gè)Znode。
五、Zookeeper特性
1、?一次性:一旦一個(gè)Wather觸發(fā)之后,Zookeeper就會(huì)將它從存儲(chǔ)中移除。
2、客戶端串行:客戶端的Wather回調(diào)處理是串行同步的過(guò)程,不要因?yàn)橐粋€(gè)Wather的邏輯阻塞整個(gè)客戶端。
3、輕量?:Wather通知的單位是WathedEvent,只包含通知狀態(tài)、事件類(lèi)型和節(jié)點(diǎn)路徑,不包含具體的事件內(nèi)容,具體的時(shí)間內(nèi)容需要客戶端主動(dòng)去重新獲取數(shù)據(jù)。
六、Zookeeper集群
- Leader:負(fù)責(zé)寫(xiě)數(shù)據(jù)。(寫(xiě)數(shù)據(jù)都有事務(wù))。
- Follower:負(fù)責(zé)讀數(shù)據(jù),節(jié)點(diǎn)的選舉和過(guò)半寫(xiě)成功。(讀數(shù)據(jù)沒(méi)有事務(wù))。
- Observer:只負(fù)責(zé)讀。
從上面的角色種,我們可以總結(jié)Zookeeper節(jié)點(diǎn)的工作狀態(tài)(服務(wù)狀態(tài))
- LOOKING:尋 找 Leader 狀態(tài)。當(dāng)服務(wù)器處于該狀態(tài)時(shí),它會(huì)認(rèn)為當(dāng)前集群中沒(méi)有 Leader,因此需要進(jìn)入 Leader 選舉狀態(tài)。
- FOLLOWING:跟隨者狀態(tài)。表明當(dāng)前服務(wù)器角色是 Follower。
- LEADING:領(lǐng)導(dǎo)者狀態(tài)。表明當(dāng)前服務(wù)器角色是 Leader。
- OBSERVING:觀察者狀態(tài)。表明當(dāng)前服務(wù)器角色是 Observer。
zxid:全局事務(wù)ID,分為兩部分:
(1)紀(jì)元(epoch)部分:epoch代表當(dāng)前集群所屬的哪個(gè)leader,leader的選舉就類(lèi)似一個(gè)朝代的更替,你前朝的劍不能斬本朝的官,用epoch代表當(dāng)前命令的有效性。
(2)計(jì)數(shù)器(counter)部分,是一個(gè)全局有序的數(shù)字,是一個(gè)遞增的數(shù)字。
七、寫(xiě)數(shù)據(jù)原理
1、寫(xiě)給leader,leader再通知其他節(jié)點(diǎn)。
2、寫(xiě)給follower,follower沒(méi)有寫(xiě)的權(quán)限,交給leader寫(xiě),leader再通知。
3、半數(shù)機(jī)制:比如上圖,zookeeper在通知其他節(jié)點(diǎn)寫(xiě)的時(shí)候,達(dá)到半數(shù)就通知客戶端寫(xiě)完成。不需要全部寫(xiě)完成。所以集群的數(shù)量一般是奇數(shù)。
八、Zookeeper怎么保證數(shù)據(jù)一致性?
由于Zookeeper只有Leader節(jié)點(diǎn)可以寫(xiě)入數(shù)據(jù),如果是其他節(jié)點(diǎn)收到寫(xiě)入數(shù)據(jù)的請(qǐng)求,則會(huì)將之轉(zhuǎn)發(fā)給Leader節(jié)點(diǎn)。
Zookeeper通過(guò)ZAB協(xié)議來(lái)實(shí)現(xiàn)數(shù)據(jù)的最終順序一致性,他是一個(gè)類(lèi)似2PC兩階段提交的過(guò)程。ZAB有2種模式:消息廣播,崩潰恢復(fù)(選舉)。
一般我們正常是消息廣播:
第一階段:廣播事務(wù)階段
1、Leader收到請(qǐng)求之后,將它轉(zhuǎn)換為一個(gè)proposal提議,并且為每個(gè)提議分配一個(gè)事務(wù)ID:zxid。
2、然后把提議放入到一個(gè)FIFO的隊(duì)列中,按照FIFO的策略發(fā)送給所有的Follower。
3、Follower收到提議之后,以事務(wù)日志的形式寫(xiě)入到本地磁盤(pán)中,寫(xiě)入成功后返回ACK給Leader。
第二階段:廣播提交操作
Leader在收到超過(guò)半數(shù)的Follower的ACK之后,即可認(rèn)為數(shù)據(jù)寫(xiě)入成功,就會(huì)發(fā)送commit命令給Follower告訴他們可以提交proposal了。
本文轉(zhuǎn)載自微信公眾號(hào)「哪吒編程」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系哪吒編程公眾號(hào)。