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