天天看點

ZooKeeper叢集Leader選舉理論解讀(初次選舉和故障恢複)

首發CSDN:徐同學呀,原創不易,轉載請注明源連結。我是徐同學,用心輸出高品質文章,希望對你有所幫助。

文章目錄

    • 一、前言
    • 二、基本概念
      • 1、伺服器角色
      • 2、票據ZXID和myid
        • (1)ZXID
        • (1)myid
    • 三、Leader選舉
      • 1、叢集第一次啟動Leader選舉
      • 2、叢集運作期間Leader選舉
        • (1)Leader故障的幾種典型場景
        • (2)故障恢複
      • 3、Observer旁觀者的好處
    • 四、要點總結
    • 五、參考資料

一、前言

ZooKeeper

參考

Paxos

算法,專門設計了一種支援崩潰恢複的原子廣播協定

Zab

Zookeeper Atomic Broadcast

),

Leader

選舉是其核心思想,也是保證

ZooKeeper

資料一緻性的關鍵所在。

ZooKeeper叢集Leader選舉理論解讀(初次選舉和故障恢複)

二、基本概念

1、伺服器角色

一個正常運作的zk叢集中,一定存在兩種伺服器角色

Leader

Follower

Leader

負責事務請求處理協調和資料同步以保證資料順序最終一緻性;

Follower

具有投票,隻讀請求可以自己處理,但是事務請求需要轉發給

Leader

。還有一種角色

Observer

,和

Follower

統稱為

Learner

,但是沒有投票權,也不參與過半數機制。

2、票據ZXID和myid

在進行

Leader

選舉時,

ZXID

myid

作為投票依據,比較服務之間

ZXID

myid

的大小來判定票投給誰,最終得票過半數的成為

Leader

(1)ZXID

ZXID

是事務ID,由

Leader

生成,是一個16進制的遞增數字,共64位(二進制),由兩部分組成:高32位代表目前

Leader

任期編号,每進行一次

Leader

選舉就加一;低32位是事務計數器,遞增,整體上是遞增的。

ZXID

的作用主要有兩個:

  • 保證資料的順序一緻性,所有事務請求統一由

    Leader

    發起提議,嚴格按

    ZXID

    順序執行,目前事務請求沒有處理完,再來新的事務請求就會阻塞。
  • ZXID

    參與選票依據,

    ZXID

    大的獲得選票。
ZooKeeper叢集Leader選舉理論解讀(初次選舉和故障恢複)

(1)myid

myid

應該比較眼熟吧,在搭建zk叢集時,每個服務節點的

dataDir

目錄下都會建立一個

myid

檔案,檔案中隻包含一個數字,且不能重複;在

zoo.cfg

配置裡也可以看到有幾行

server.A=B:C:D

,A代表的就是

myid

myid

作為

zk

服務的

ServerId

,簡稱

SID

,并且也是選票依據,當

ZXID

相等時,

myid

大的獲得選票。

三、Leader選舉

1、叢集第一次啟動Leader選舉

因為3個服務節點的zk叢集

Leader

選舉可能過于簡單,是以下面以5個服務節點組成的zk叢集來看看

Leader

選舉的過程。

第一次啟動,都處于初始狀态,

ZXID

都是0,

myid

分别為1、2、3、4、5。票據

(ZXID,myid)

分别為

(0,1)

(0,2)

(0,3)

(0,4)

(0,5)

(此概念不涉及源碼層面,但是原理上差不多),如下是具體的投票選舉過程:

  • myid=1

    的伺服器啟動,發起一次投票,伺服器1給自己投1票,票數不過半,選舉無法完成。
  • myid=2

    的伺服器啟動,再發起一次投票,伺服器1和伺服器2分别給自己投一票。
  • 伺服器1和伺服器2交換選票資訊,先比較

    ZXID

    ,都是0,再 比較

    myid

    ,伺服器2的

    myid

    比伺服器1大,是以伺服器1的票據更改為

    (0,2)

    ,伺服器2不需要更改。
  • 統計選票,伺服器1和伺服器2變更選票資訊後再次交換選票,伺服器1和伺服器2都有兩張一樣的票

    (0,2)

    ,意為伺服器2有兩票,但是票數不過半,無法完成投票。
  • myid=3

    的伺服器啟動,發起投票,此時伺服器1和2持有的票據都是

    (0,2)

    ,伺服器3的票據為

    (0,3)

    ,互相交換選票(每個伺服器的票據都要廣播給其他具有投票權的伺服器),伺服器3的

    myid

    比伺服器2的 大,伺服器1和2變更票據為

    (0,3)

    ,伺服器3保持不變。
  • 再次統計選票,伺服器3有三張票,伺服器1和2都是零票。伺服器3持有的票數過半,

    Leader

    選舉完成,伺服器3成為

    Leader

    ,伺服器1和2成為

    Follower

  • myid=4

    的伺服器啟動,發現叢集中已經有

    Leader

    了,就變更自己的角色狀态為

    Follower

  • myid=5

    的伺服器啟動,同理也變更自己的角色狀态為

    Follower

過程還是比較簡單,也很容易了解,對投票過程總結3點:

  • 交換選票,每個伺服器将自己持有的票據廣播給其他具有投票權的伺服器。
  • 變更選票,票據比較,所有伺服器都将自己的選票資訊更新為那個

    ZXID

    最大的或者

    myid

    最大的伺服器的選票,這就相當于投票了。
  • 統計選票,每個伺服器再廣播一次自己持有的票據,每個伺服器判斷自己接收到的相同票據數量是否過半數,是就推選該票據的

    myid

    對應的伺服器成為

    Leader

    ,其他都為

    Follower

如下圖是僞叢集伺服器數量3的第一次啟動過程示範:

ZooKeeper叢集Leader選舉理論解讀(初次選舉和故障恢複)

2、叢集運作期間Leader選舉

zk叢集正常運作期間,一旦選出了Leader,那麼所有伺服器的角色都不會再發生變化。後啟動的伺服器發現有

Leader

,就直接變更自己的角色為

Follower

Follower

挂了,隻要正常運作的伺服器數量還在半數以上,整個叢集就還可以正常對外提供服務。

但是一旦

Leader

所在的伺服器挂了,如果叢集中正常運作的機器半數以上,就得重選

Leader

(1)Leader故障的幾種典型場景

Leader

在挂掉的時候,可能還有一些寫操作沒有完成,可能會造成剩下的伺服器資料不一緻。如下是幾種

Leader

故障的場景:

  • Leader

    完成了所有事務

    COMMIT

    ,然後挂了,此時過半數以上的伺服器的資料是一緻的,重選

    Leader

    基本不影響。
  • Leader

    在接收到事務請求至最後廣播

    COMMIT

    之前的某個時刻挂了,這都屬于未完成的事務請求,即使有伺服器已經把事務請求持久化到了日志檔案,但是還沒有完成最後的

    COMMIT

    将資料同步到記憶體資料庫。未完成的事務會被丢棄。
  • Leader

    在廣播

    COMMIT

    的過程中挂了,這就導緻某些收到了

    COMMIT

    完成了事務,有些沒收到,還處于持久化事務日志檔案的階段,最終導緻資料不一緻。

(2)故障恢複

故障恢複包括兩部分:

Leader

選舉和資料恢複。

Leader

重新選舉的過程和第一次啟動選舉一樣,不再贅述。成為新Leader必須滿足以下兩個條件:

  • Leader

    ZXID

    是所有伺服器中最大的,這就可以最大限度的恢複資料。
  • Leader

    不能包含未

    COMMIT

    的事務提議,如果事務日志檔案中有未同步到記憶體資料庫的事務将會復原丢棄。

新Leader選舉出來以後,就開始恢複資料了。為了叢集全局資料一緻性,所有的

Follower

上的資料都必須和Leader的一樣:

  • Leader

    有的

    Follower

    沒有,

    Leader

    将這些事務同步給

    Follower

  • Leader

    沒有的,

    Follower

    有,

    Follower

    需要復原丢棄這些所謂超前的事務。

注:如果原先叢集運作了一段時間,産生了資料不一緻,然後全部停機後,再一個個重新開機,最好是先去看看每個服務的事務日志檔案内記錄的最後送出的

ZXID

,最大的那個服務先重新開機,否則可能會導緻

Leader

已經選舉好了,後面一個帶着最全資料的服務節點重新開機了,反而要復原事務。

需要注意的是在Leader選舉的過程中,叢集是處于無法正常對外提供服務的狀态。

3、Observer旁觀者的好處

Leader

選舉的過程中一直沒有說

Observer

,原因是

Observer

沒有投票權,但是它除了沒有投票權,不參與過半機制外,和

Follower

差不多,也可以通過用戶端連接配接,也可以從

Leader

同步資料。

Observer

的機制可以應用在擴容上,不僅可以實作資料的動态遷移和擴容,還可以就隻作為一個與世無争的旁觀者,不影響叢集的正常寫性能,還提升讀性能,可以用在異地機房資料同步。

ZooKeeper叢集Leader選舉理論解讀(初次選舉和故障恢複)

四、要點總結

熟悉

Leader

選舉的底層理論,可以很好的應對叢集的遷移和擴縮容。

ZooKeeper

在Leader選舉期間和正常服務個數不過半數都無法對外提供服務,并且會丢棄一些未完成的事務,以保證資料一緻,是以它是

CP

,即保證資料一緻性(

Consistency

)和分區容錯性(

Partition Tolerance

),但不保證可用性(

Available

)。

本篇要點總結如下:

  1. Leader

    選舉,先比較

    ZXID

    ZXID

    較大的獲得更多選票,

    ZXID

    相等,比較

    myid

    myid

    較大的獲得更多選票。
  2. 票數過半即可選出

    Leader

    ,後來者則自動成為

    Follower

  3. 故障恢複,

    Leader

    重選,會丢棄未完成的事務。
  4. Observer

    雖然沒有投票權,也不決定過半機制,但是同樣可以和

    Leader

    建立連接配接,同步資料。這一特點可以用于異地機房同步資料和擴容上,極大提升讀性能但對寫性能影響極小。

五、參考資料

  1. 書籍:《從Paxos到Zookeeper分布式一緻性原理與實踐》
  2. https://www.bilibili.com/video/BV1to4y1C7gw
  3. Migrating Kafka’s Zookeeper With No Downtime

如若文章有錯誤了解,歡迎批評指正,同時非常期待你的評論、點贊和收藏。

如果想了解更多優質文章,和我更密切的學習交流,請關注如下同名公衆号【徐同學呀】,期待你的加入。

注:《ZooKeeper-分布式過程協同技術詳解》和 《從Paxos到Zookeeper分布式一緻性原理與實踐》pdf版本由于版權問題無法在CSDN上傳,有需要這兩本PDF的請關注公衆号:徐同學呀,回複zkpdf擷取。

ZooKeeper叢集Leader選舉理論解讀(初次選舉和故障恢複)