Zookeeper與Paxos

Apache Zookeeper是由Apache Hadoop的子項(xiàng)目發(fā)展而來,于2010年11月正式成為Apache頂級(jí)項(xiàng)目。Zookeeper為分布式應(yīng)用提供高效且可靠的分布式協(xié)調(diào)服務(wù),提供了統(tǒng)一命名服務(wù)、配置管理、分布式鎖等分布式的基礎(chǔ)服務(wù)。Zookeeper并沒有直接采用Paxos算法,而是采用了一種被稱為ZAB(Zookeeper Atomic Broadcast)的一致性協(xié)議。

初識(shí)Zookeeper

Zookeeper是一個(gè)開源的分布式協(xié)調(diào)服務(wù),由Yahoo創(chuàng)建,是Google Chubby的開源實(shí)現(xiàn)。Zookeeper將那些復(fù)雜且容易出錯(cuò)的分布式一致性服務(wù)封裝起來,構(gòu)成一個(gè)高效可靠的原語集,并以一系列簡(jiǎn)單易用的接口提供給用戶使用。

分布式應(yīng)用程序可以基于Zookeeper實(shí)現(xiàn)例如數(shù)據(jù)發(fā)布/訂閱、負(fù)載均衡、命名服務(wù)、協(xié)調(diào)通知、集群管理、Master選舉、分布式鎖、分布式隊(duì)列等功能。Zookeeper可以保證如下分布式一致性特性。

1、順序一致性:從同一個(gè)客戶端發(fā)起的事務(wù)請(qǐng)求,最終將會(huì)嚴(yán)格地按照其發(fā)起順序被應(yīng)用到Zookeeper中;

2、原子性:所有事務(wù)的請(qǐng)求結(jié)果在整個(gè)集群中所有機(jī)器上的應(yīng)用情況是一致的,也就是說,要么在整個(gè)集群中所有機(jī)器上都成功應(yīng)用了某一個(gè)事務(wù),要么都沒有應(yīng)用,沒有中間狀態(tài);

3、單一視圖:無論客戶端連接的是哪個(gè)Zookeeper服務(wù)器,其看到的服務(wù)端數(shù)據(jù)模型都是一致的。

4、實(shí)時(shí)性:Zookeeper僅僅保證在一定的時(shí)間內(nèi),客戶端最終一定能夠從服務(wù)端上讀到最終的數(shù)據(jù)狀態(tài)。

Zookeeper的設(shè)計(jì)目標(biāo)

目標(biāo)一:簡(jiǎn)單的數(shù)據(jù)模型

Zookeeper使得分布式程序能通過一個(gè)共享式的、樹形結(jié)構(gòu)的名字空間來進(jìn)行相互協(xié)調(diào)。

樹形結(jié)構(gòu)的名字空間是指Zookeeper服務(wù)器內(nèi)存中的一個(gè)數(shù)據(jù)模型,由一系列被稱為ZNode的數(shù)據(jù)節(jié)點(diǎn)組成,類似一個(gè)文件系統(tǒng)。

目標(biāo)二:可以構(gòu)建集群

組成Zookeeper集群的每臺(tái)機(jī)器都會(huì)在內(nèi)存中維護(hù)當(dāng)前服務(wù)器狀態(tài),并且每臺(tái)機(jī)器都保持通訊。只要集群中超過一半機(jī)器能夠正常工作,整個(gè)集群就能對(duì)外正常服務(wù)。

目標(biāo)三:順序訪問

對(duì)于來自客戶端的每個(gè)更新請(qǐng)求,Zookeeper都會(huì)分配一個(gè)全局唯一遞增編號(hào),這個(gè)編號(hào)反映了所有事物操作的先后順序,應(yīng)用程序可以使用Zookeeper的這個(gè)特性來實(shí)現(xiàn)更加高層的同步原語。

目標(biāo)四:高性能

Zookeeper將全量數(shù)據(jù)存儲(chǔ)在內(nèi)存中直接對(duì)外服務(wù)(除事務(wù)請(qǐng)求),尤其適合于讀操作為主的應(yīng)用場(chǎng)景。

Zookeeper基本概念


集群角色

最典型的集群角色是Master/Slave模式,Master處理所有寫操作,Slave提供讀服務(wù)。

在Zookeeper中,有Leader、Follower、Observer三種角色。集群中所有機(jī)器通過一個(gè)Leader選舉來決定一臺(tái)機(jī)器作為L(zhǎng)eader,Leader為客戶端提供讀和寫服務(wù)。Follower和Observer都提供讀服務(wù),區(qū)別在于Observer機(jī)器不參與選舉,也不參與寫操作的“過半寫成功”策略,因此Observe可以在不影響寫性能的情況下提升集群的讀性能。

會(huì)話

客戶端與Zookeeper是TCP長(zhǎng)連接,默認(rèn)對(duì)外端口是2181,通過這個(gè)連接,客戶端保持和服務(wù)器的心跳以維護(hù)連接,也能向Zookeeper發(fā)送請(qǐng)求并響應(yīng),同時(shí)還可以接收到注冊(cè)通知。

數(shù)據(jù)節(jié)點(diǎn)(ZNode)

Zookeeper所有數(shù)據(jù)都在內(nèi)存中,模型類似一顆文件樹,ZNode Tree,每個(gè)ZNode節(jié)點(diǎn)都會(huì)保存自己的數(shù)據(jù)內(nèi)容和一系列屬性。

ZNode分為持久節(jié)點(diǎn)和臨時(shí)節(jié)點(diǎn),后者和客戶端會(huì)話綁定。

版本

每個(gè)ZNode,Zookeeper都會(huì)維護(hù)一個(gè)Stat數(shù)據(jù)結(jié)構(gòu)記錄這個(gè)ZNode的三個(gè)數(shù)據(jù)版本:當(dāng)前ZNode版本version、當(dāng)前ZNode子節(jié)點(diǎn)版本cversion、和當(dāng)前Node的ACL版本aversion。

Watcher

事件監(jiān)聽是Zookeeper的重要特性,他允許客戶端在指定節(jié)點(diǎn)注冊(cè)Watcher,并且在事件被觸發(fā)后通知客戶端。

ACL

Access Control Lists,定義了5中權(quán)限:

Create、Read、Write、Delete、Admin

ZAB協(xié)議

在ZooKeeper中所有的事務(wù)請(qǐng)求都由一個(gè)主服務(wù)器也就是Leader來處理,其他服務(wù)器為Follower,Leader將客戶端的事務(wù)請(qǐng)求轉(zhuǎn)換為事務(wù)Proposal,并且將Proposal分發(fā)給集群中其他所有的Follower,然后Leader等待Follwer反饋,當(dāng)有過半數(shù)(>=N/2+1)的Follower反饋信息后,Leader將再次向集群內(nèi)Follower廣播Commit信息,Commit為將之前的Proposal提交。

ZAB協(xié)議中存在著三種狀態(tài),每個(gè)節(jié)點(diǎn)都屬于以下三種中的一種:

1.Looking:系統(tǒng)剛啟動(dòng)時(shí)或者Leader崩潰后正處于選舉狀態(tài)

2.Following:Follower節(jié)點(diǎn)所處的狀態(tài),F(xiàn)ollower與Leader處于數(shù)據(jù)同步階段;

3.Leading:Leader所處狀態(tài),當(dāng)前集群中有一個(gè)Leader為主進(jìn)程;

ZooKeeper啟動(dòng)時(shí)所有節(jié)點(diǎn)初始狀態(tài)為L(zhǎng)ooking,這時(shí)集群會(huì)嘗試選舉出一個(gè)Leader節(jié)點(diǎn),選舉出的Leader節(jié)點(diǎn)切換為L(zhǎng)eading狀態(tài);當(dāng)節(jié)點(diǎn)發(fā)現(xiàn)集群中已經(jīng)選舉出Leader則該節(jié)點(diǎn)會(huì)切換到Following狀態(tài),然后和Leader節(jié)點(diǎn)保持同步;當(dāng)Follower節(jié)點(diǎn)與Leader失去聯(lián)系時(shí)Follower節(jié)點(diǎn)則會(huì)切換到Looking狀態(tài),開始新一輪選舉;在ZooKeeper的整個(gè)生命周期中每個(gè)節(jié)點(diǎn)都會(huì)在Looking、Following、Leading狀態(tài)間不斷轉(zhuǎn)換;

選舉出Leader節(jié)點(diǎn)后ZAB進(jìn)入原子廣播階段,這時(shí)Leader為和自己同步的每個(gè)節(jié)點(diǎn)Follower創(chuàng)建一個(gè)操作序列,一個(gè)時(shí)期一個(gè)Follower只能和一個(gè)Leader保持同步,Leader節(jié)點(diǎn)與Follower節(jié)點(diǎn)使用心跳檢測(cè)來感知對(duì)方的存在;當(dāng)Leader節(jié)點(diǎn)在超時(shí)時(shí)間內(nèi)收到來自Follower的心跳檢測(cè)那Follower節(jié)點(diǎn)會(huì)一直與該節(jié)點(diǎn)保持連接;若超時(shí)時(shí)間內(nèi)Leader沒有接收到來自過半Follower節(jié)點(diǎn)的心跳檢測(cè)或TCP連接斷開,那Leader會(huì)結(jié)束當(dāng)前周期的領(lǐng)導(dǎo),切換到Looking狀態(tài),所有Follower節(jié)點(diǎn)也會(huì)放棄該Leader節(jié)點(diǎn)切換到Looking狀態(tài),然后開始新一輪選舉。

ZAB協(xié)議定義了選舉(election)、發(fā)現(xiàn)(discovery)、同步(sync)、廣播(Broadcast)四個(gè)階段;ZAB選舉(election)時(shí)當(dāng)Follower存在ZXID(事務(wù)ID)時(shí)判斷所有Follower節(jié)點(diǎn)的事務(wù)日志,只有l(wèi)astZXID的節(jié)點(diǎn)才有資格成為L(zhǎng)eader,這種情況下選舉出來的Leader總有最新的事務(wù)日志,基于這個(gè)原因所以ZooKeeper實(shí)現(xiàn)的時(shí)候把發(fā)現(xiàn)(discovery)與同步(sync)合并為恢復(fù)(recovery)階段;

1.Election:在Looking狀態(tài)中選舉出Leader節(jié)點(diǎn),Leader的lastZXID總是最新的;

2.Discovery:Follower節(jié)點(diǎn)向準(zhǔn)Leader推送FOllOWERINFO,該信息中包含了上一周期的epoch,接受準(zhǔn)Leader的NEWLEADER指令,檢查newEpoch有效性,準(zhǔn)Leader要確保Follower的epoch與ZXID小于或等于自身的;

3.sync:將Follower與Leader的數(shù)據(jù)進(jìn)行同步,由Leader發(fā)起同步指令,最總保持集群數(shù)據(jù)的一致性;

4.Broadcast:Leader廣播Proposal與Commit,F(xiàn)ollower接受Proposal與Commit;

5.Recovery:在Election階段選舉出Leader后本階段主要工作就是進(jìn)行數(shù)據(jù)的同步,使Leader具有highestZXID,集群保持?jǐn)?shù)據(jù)的一致性;

選舉(Election)

election階段必須確保選出的Leader具有highestZXID,否則在Recovery階段沒法保證數(shù)據(jù)的一致性,Recovery階段Leader要求Follower向自己同步數(shù)據(jù)沒有Follower要求Leader保持?jǐn)?shù)據(jù)同步,所有選舉出來的Leader要具有最新的ZXID;

在選舉的過程中會(huì)對(duì)每個(gè)Follower節(jié)點(diǎn)的ZXID進(jìn)行對(duì)比只有highestZXID的Follower才可能當(dāng)選Leader;

選舉流程:

1. 每個(gè)Follower都向其他節(jié)點(diǎn)發(fā)送選自身為L(zhǎng)eader的Vote投票請(qǐng)求,等待回復(fù);

2. Follower接受到的Vote如果比自身的大(ZXID更新)時(shí)則投票,并更新自身的Vote,否則拒絕投票;

3. 每個(gè)Follower中維護(hù)著一個(gè)投票記錄表,當(dāng)某個(gè)節(jié)點(diǎn)收到過半的投票時(shí),結(jié)束投票并把該Follower選為L(zhǎng)eader,投票結(jié)束;

ZAB協(xié)議中使用ZXID作為事務(wù)編號(hào),ZXID為64位數(shù)字,低32位為一個(gè)遞增的計(jì)數(shù)器,每一個(gè)客戶端的一個(gè)事務(wù)請(qǐng)求時(shí)Leader產(chǎn)生新的事務(wù)后該計(jì)數(shù)器都會(huì)加1,高32位為L(zhǎng)eader周期epoch編號(hào),當(dāng)新選舉出一個(gè)Leader節(jié)點(diǎn)時(shí)Leader會(huì)取出本地日志中最大事務(wù)Proposal的ZXID解析出對(duì)應(yīng)的epoch把該值加1作為新的epoch,將低32位從0開始生成新的ZXID;ZAB使用epoch來區(qū)分不同的Leader周期;

恢復(fù)(Recovery)

在election階段選舉出來的Leader已經(jīng)具有最新的ZXID,所有本階段的主要工作是根據(jù)Leader的事務(wù)日志對(duì)Follower節(jié)點(diǎn)數(shù)據(jù)進(jìn)行更新;

Leader:Leader生成新的ZXID與epoch,接收Follower發(fā)送過來的FOllOWERINFO(含有當(dāng)前節(jié)點(diǎn)的LastZXID)然后往Follower發(fā)送NEWLEADER;Leader根據(jù)Follower發(fā)送過來的LastZXID根據(jù)數(shù)據(jù)更新策略向Follower發(fā)送更新指令;

同步策略:

1.SNAP:如果Follower數(shù)據(jù)太老,Leader將發(fā)送快照SNAP指令給Follower同步數(shù)據(jù);

2.DIFF:Leader發(fā)送從Follolwer.lastZXID到Leader.lastZXID議案的DIFF指令給Follower同步數(shù)據(jù);

3.TRUNC:當(dāng)Follower.lastZXID比Leader.lastZXID大時(shí),Leader發(fā)送從Leader.lastZXID到Follower.lastZXID的TRUNC指令讓Follower丟棄該段數(shù)據(jù);

Follower:往Leader發(fā)送FOLLOERINFO指令,Leader拒絕就轉(zhuǎn)到Election階段;接收Leader的NEWLEADER指令,如果該指令中epoch比當(dāng)前Follower的epoch小那么Follower轉(zhuǎn)到Election階段;Follower還有主要工作是接收SNAP/DIFF/TRUNC指令同步數(shù)據(jù)與ZXID,同步成功后回復(fù)ACKNETLEADER,然后進(jìn)入下一階段;Follower將所有事務(wù)都同步完成后Leader會(huì)把該節(jié)點(diǎn)添加到可用Follower列表中;

SNAP與DIFF用于保證集群中Follower節(jié)點(diǎn)已經(jīng)Committed的數(shù)據(jù)的一致性,TRUNC用于拋棄已經(jīng)被處理但是沒有Committed的數(shù)據(jù);

廣播(Broadcast)

客戶端提交事務(wù)請(qǐng)求時(shí)Leader節(jié)點(diǎn)為每一個(gè)請(qǐng)求生成一個(gè)事務(wù)Proposal,將其發(fā)送給集群中所有的Follower節(jié)點(diǎn),收到過半Follower的反饋后開始對(duì)事務(wù)進(jìn)行提交,ZAB協(xié)議使用了原子廣播協(xié)議;在ZAB協(xié)議中只需要得到過半的Follower節(jié)點(diǎn)反饋Ack就可以對(duì)事務(wù)進(jìn)行提交,這也導(dǎo)致了Leader幾點(diǎn)崩潰后可能會(huì)出現(xiàn)數(shù)據(jù)不一致的情況,ZAB使用了崩潰恢復(fù)來處理數(shù)字不一致問題;消息廣播使用了TCP協(xié)議進(jìn)行通訊所有保證了接受和發(fā)送事務(wù)的順序性。廣播消息時(shí)Leader節(jié)點(diǎn)為每個(gè)事務(wù)Proposal分配一個(gè)全局遞增的ZXID(事務(wù)ID),每個(gè)事務(wù)Proposal都按照ZXID順序來處理;

Leader節(jié)點(diǎn)為每一個(gè)Follower節(jié)點(diǎn)分配一個(gè)隊(duì)列按事務(wù)ZXID順序放入到隊(duì)列中,且根據(jù)隊(duì)列的規(guī)則FIFO來進(jìn)行事務(wù)的發(fā)送。Follower節(jié)點(diǎn)收到事務(wù)Proposal后會(huì)將該事務(wù)以事務(wù)日志方式寫入到本地磁盤中,成功后反饋Ack消息給Leader節(jié)點(diǎn),Leader在接收到過半Follower節(jié)點(diǎn)的Ack反饋后就會(huì)進(jìn)行事務(wù)的提交,以此同時(shí)向所有的Follower節(jié)點(diǎn)廣播Commit消息,F(xiàn)ollower節(jié)點(diǎn)收到Commit后開始對(duì)事務(wù)進(jìn)行提交。

總的來說,ZAB主要是用來構(gòu)建一個(gè)高可用的分布式數(shù)據(jù)主備系統(tǒng),而Paxos則是構(gòu)建一個(gè)分布式的一致性狀態(tài)機(jī)系統(tǒng)。

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

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

  • 一個(gè)真正的寫數(shù)據(jù)流程是怎么樣的?一個(gè)真正的讀數(shù)據(jù)流程是怎么樣的?一個(gè)真正的同步數(shù)據(jù)流程是怎么樣的?從哪里到哪里?什...
    時(shí)待吾閱讀 4,317評(píng)論 0 14
  • 本文將從系統(tǒng)模型、序列化與協(xié)議、客戶端工作原理、會(huì)話、服務(wù)端工作原理以及數(shù)據(jù)存儲(chǔ)等方面來揭示ZooKeeper的技...
    端木軒閱讀 3,915評(píng)論 0 42
  • 淺談分布式服務(wù)協(xié)調(diào)技術(shù) Zookeeper Google的三篇論文影響了很多很多人,也影響了很多很多系統(tǒng)。這三篇論...
    algernoon閱讀 1,704評(píng)論 1 12
  • ZooKeeper為分布式應(yīng)用提供了高效且可靠的分布式協(xié)調(diào)服務(wù),提供了諸如tong'yi統(tǒng)一命名服務(wù)、配置管理和分...
    端木軒閱讀 2,142評(píng)論 2 12
  • 十月計(jì)劃其實(shí)八月就已經(jīng)做了,然而事情總有改變。 十月份的周末基本上都是滿的。 現(xiàn)階段就是期待能夠保持健康的作息,平...
    psychology凡心閱讀 288評(píng)論 0 0

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