Zookeeper簡單介紹

Zookeeper是為了解決大型分布式系統(tǒng)的一系列問題而開發(fā)的一套協(xié)調(diào)服務(wù),它將復(fù)雜且容易出錯的分布一致性服務(wù)封裝起來,構(gòu)成了一個高效可靠的原語集,并以簡單易用的接口提供給用戶使用。它提供了發(fā)布/訂閱、分布式協(xié)調(diào)/通知、配置管理、集群管理、主從協(xié)調(diào)、分布式鎖等功能。

要明白Zookeeper的功能,先了解下分布式系統(tǒng)和這樣的系統(tǒng)遇到的問題

分布式系統(tǒng)

硬件/軟件組件分布在不同的計算機上,彼此之間通過消息進行協(xié)調(diào)和通信的系統(tǒng)即稱為分布式系統(tǒng)

分布式系統(tǒng)的特點

分布性? 分布式系統(tǒng)的布置在不同的服務(wù)器、不同的機架甚至不同的機房、不同的城市,它的物理位置很分散,而且可能由于環(huán)境因素隨時發(fā)生變化

對等性? 分布式系統(tǒng)無主從之分,每臺服務(wù)器都是相對公平的提供服務(wù),這樣方便實現(xiàn)數(shù)據(jù)及服務(wù)的高可用

并發(fā)性? ? 分布式系統(tǒng)可能出現(xiàn)同時對同一份數(shù)據(jù)進行操作的情況

缺乏全局時鐘? ? 各個服務(wù)之間的時間先后順序很難定義

故障隨時發(fā)生? ? 由于系統(tǒng)服務(wù)器眾多,故障也就隨時有可能發(fā)生

分布式系統(tǒng)的問題

通信異常? ? 由于分布式系統(tǒng)分布式的特點,網(wǎng)絡(luò)不可避免的會出現(xiàn)問題

網(wǎng)絡(luò)分區(qū)? ? 俗稱腦裂,由于分布式系統(tǒng)部分服務(wù)器的延遲,集群中只有部分節(jié)點能處理請求,而這樣就有可能造成斷網(wǎng)的節(jié)點也在處理請求,而斷網(wǎng)的節(jié)點間可能構(gòu)成了新的分布式系統(tǒng)對外提供服務(wù),這樣就導(dǎo)致了數(shù)據(jù)不一致

三態(tài)? ? 單機系統(tǒng)對一個請求的處理有成功、失敗兩種很明確的狀態(tài),但分布式系統(tǒng)還可以有超時狀態(tài)

節(jié)點故障

分布式系統(tǒng)-CAP定理

CAP即Consistency(一致性)、Availability(可用性)、Partition tolerance(分區(qū)容錯性),CAP定理指出:任何系統(tǒng) 不可能同時滿足上述三個特性,最多只能滿足其中兩項

而分區(qū)容錯性對于分布式系統(tǒng)來說是必須解決的問題,因而對于系統(tǒng)的優(yōu)化主要集中在一致性和可用性兩個方面

Zookeeper使用了最終一致性來使一致性和可用性達到了平衡,它在在解決分區(qū)容錯性和可用性的同時,保證數(shù)據(jù)達到最終一致性

Zookeeper特性

最終一致性? ? 系統(tǒng)數(shù)據(jù)經(jīng)過一定時間后,最終能達到一致

順序性? ? 從同一個客戶端發(fā)起的事務(wù)請求,最終會嚴格地按照其發(fā)送順序被應(yīng)用到Zookeeper中

可靠性? ? 一旦服務(wù)器成功應(yīng)用一個事務(wù)并完成了客戶端的響應(yīng),那么該事務(wù)所引起的服務(wù)端狀態(tài)變更會一直被保留下去

實時性? ??不能保證兩個客戶端能同時得到剛更新的數(shù)據(jù),如果需要最新數(shù)據(jù),需要在讀數(shù)據(jù)前調(diào)用sync()接口

原子性? ? 一次數(shù)據(jù)更新要么成功,要么失敗,沒有中間狀態(tài)

單一視圖? ? 無論客戶端連接到哪臺服務(wù)器,看到的數(shù)據(jù)模型都是一致的

Zookeeper的架構(gòu)


zookeeper總體架構(gòu)


Zookeeper角色簡介

Leader : 從所有的follower中選舉出來,為客戶端提供讀寫服務(wù)及發(fā)起投票和決議,處理事務(wù)請求,更新系統(tǒng)狀態(tài)

Follower: Leaner角色的一種,負責客戶端的讀請求服務(wù),如果收到寫請求,則轉(zhuǎn)發(fā)給Leader,同時負責選舉

Observer:Leaner角色的一種,負責客戶端的讀請求服務(wù),將客戶端的寫請求轉(zhuǎn)發(fā)給Leader,但不負責選舉,Observer存在的目的是為了擴展系統(tǒng),提高讀寫速度。

Client: 請求發(fā)起方

Zookeeper寫入

數(shù)據(jù)寫入的核心算法:ZAB算法


Zookeeper寫入圖示

1. 客戶端向Follower發(fā)送寫請求

2. Follower收到客戶端的寫請求后,將寫請求發(fā)送給Leader

3.Leader接收到以后開始發(fā)起投票并通知Follwer進行投票

4.Follwer把投票結(jié)果發(fā)送給Leader

5.Leader將結(jié)果匯總后如果需要寫入,則開始寫入同時把寫入操作通知給Leader,然后commit;

6.Follwer把請求結(jié)果返回給Client

Zookeeper選舉簡介

服務(wù)器四種狀態(tài)

LOOKING :尋找leader狀態(tài),處于該狀態(tài)需要進入選舉流程

LEADING: 領(lǐng)導(dǎo)者狀態(tài),Leader已經(jīng)選舉出來,表明當前服務(wù)角色為Leader

FOLLOWING: 跟隨者狀態(tài),Leader已經(jīng)選舉出來,表明當前服務(wù)角色為Follower

OBSERVER: 觀察者狀態(tài),表明當前服務(wù)角色Observer

事務(wù)ID:用ZXID表示,為一個64位數(shù)字,由Leader統(tǒng)一分配,全局唯一,不斷遞增

選舉(全新啟動)


每個Server發(fā)出一個投票,內(nèi)容為(myid,ZXID)(兩臺機器啟動)

接收每個Server的投票

處理投票(與自己的廣播消息進行對比,事務(wù)ID、myid等)

統(tǒng)計投票

改變服務(wù)器狀態(tài)

選舉(運行期間,Leader掛)

與全新啟動狀態(tài)類似

數(shù)據(jù)模型Znode

Zookeeper特有的數(shù)據(jù)節(jié)點,視圖結(jié)構(gòu)類似于Linux文件系統(tǒng),沒有目錄和文件的概念

Znode是Zookeeper中數(shù)據(jù)的最小單元

Znode上可以保存數(shù)據(jù)通過掛載子節(jié)點構(gòu)成一個樹狀的層次化命名空間

Znode樹的根由“/”開始


Znode樹結(jié)構(gòu)

Znode的生命周期取決于其節(jié)點類型

節(jié)點類型

持久節(jié)點

臨時節(jié)點

順序節(jié)點

組合節(jié)點

持久節(jié)點

持久順序節(jié)點

臨時節(jié)點(不允許在臨時節(jié)點中創(chuàng)建子節(jié)點,臨時節(jié)點的生命周期和客戶端會話綁定,如果客戶端與會話失效,節(jié)點會被Zookeeper自動刪除,會話由客戶端與zookeeper通過心跳保持周期性聯(lián)系)

臨時順序節(jié)點

Znode版本

版本類型

dataVersion:當前數(shù)據(jù)節(jié)點的版本號

cVersion:當前數(shù)據(jù)節(jié)點子節(jié)點的版本號

aVersion:當前數(shù)據(jù)節(jié)點ACL權(quán)限變更版本號

如何保證分布式數(shù)據(jù)原子性操作

悲觀鎖 事務(wù)執(zhí)行的整個過程中對數(shù)據(jù)進行加鎖

樂觀鎖 事務(wù)進行更新/提交之前對數(shù)據(jù)進行檢查,如果數(shù)據(jù)有其他數(shù)據(jù)進行修改,則回滾,如果沒有,則提交(適合數(shù)據(jù)并發(fā)量不大的情況)

zookeeper中使用version實現(xiàn)樂觀鎖的寫入校驗:

// 獲取當前請求的Version

version = setDataRequest.getVersion();

// 獲取當前服務(wù)器上該數(shù)據(jù)的最新Versionint

currentVersion = nodeRecord.stat.getVersion();

if(version != -1 && version != currentVersion) {? ?

? ? throw new KeeperException.BadVersionException(path);

}

version = currentVersion + 1;


Znode狀態(tài)


Znode狀態(tài)

Znode監(jiān)聽機制


Znode監(jiān)聽

客戶端在集群中注冊監(jiān)聽事件,集群中的WatchManager存儲此監(jiān)聽,如果監(jiān)聽事件發(fā)生,則執(zhí)行相應(yīng)的回調(diào)函數(shù)

Zookeeper的應(yīng)用場景

統(tǒng)一命名服務(wù)

對應(yīng)用/服務(wù)進行統(tǒng)一命名,便于識別不同服務(wù)

按照層次結(jié)構(gòu)組織服務(wù)/應(yīng)用名稱? ? 可將服務(wù)名稱及地址信息寫到Zookeeper上,客戶端通過Zookeeper獲取可用服務(wù)列表

全局唯一ID? 依靠Zookeeper的順序節(jié)點可以輕松生成全局唯一ID

配置管理

配置信息寫入Zookeeper的一個Znode上;

各節(jié)點監(jiān)聽Znode

Znode數(shù)據(jù)變化,通知各節(jié)點更新

集群管理

實時掌握每個節(jié)點的狀態(tài)? ? 將節(jié)點信息寫入到一個Znode上,監(jiān)聽這個Znode可獲取它的實時狀態(tài)變化

分布式鎖

Zookeeper強一致? ? 多個客戶端在Zookeeper上創(chuàng)建相同的Znode,只有一個創(chuàng)建成功

鎖的獨占性? ? 多個客戶端同時在Zookeeper上創(chuàng)建相同的Znode,創(chuàng)建成功的那個客戶端得到鎖,其他客戶端等待

鎖的時序? ? 各個客戶端在某個Znode下創(chuàng)建臨時znode(類型為CreateMode.EPHEMERAL_SEQUENTIAL),這樣該Znode可掌握全局訪問時序

分布式隊列

先入先出隊列

同步隊列? ? 當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有成員到達,比如一個聚合計算開始之前需要并行計算的很多子任務(wù)全部完成才能進行,可以為這個聚合計算創(chuàng)建一個Znode,同時監(jiān)聽這個Znode,其他并行子任務(wù)在這個Znode下創(chuàng)建臨時節(jié)點,每次Znode都會發(fā)出通知,接收到通知統(tǒng)計子節(jié)點個數(shù),直到達到所有的子任務(wù)數(shù)

Zookeeper的介紹就先這些,如有疏漏,敬請指正

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容