分佈式技術架構原理解析之協調與同步(二)分佈式選舉

1 概述

我們大家都知道集羣一般是由兩個或兩個以上的服務器組建而成,每個服務器都是一個節點。也會聽到數據庫集羣、管理集羣等概念,也知道數據庫集羣提供了讀寫功能,管理集羣提供了管理、故障恢復等功能。那麼對於一個集羣來說,多個節點到底是怎麼協同,怎麼管理的呢?比如,數據庫集羣,如何保證寫入的數據在每個節點上都一致呢?答案是選一個“領導”來負責調度和管理集羣中其他節點。這個“領導”,在分佈式中叫做主節點,而選“領導”的過程在分佈式領域中叫作分佈式選舉。選舉的作用就是選出一個主節點,由它來協調和管理其他節點,以保證集羣有序運行和節點間數據的一致性。

2 分佈式選舉的算法

2.1 Bully 算法

Bully 算法是一種霸道的集羣選主算法,爲什麼說是霸道呢?因爲它的選舉原則是“長者”爲大,即在所有活着的節點中,選取 ID 最大的節點作爲主節點。
在 Bully 算法中,節點的角色有兩種:普通節點主節點初始化時,所有節點都是平等的,都是普通節點,並且都有成爲主的權利。但是,當選主成功後,有且僅有一個節點成爲主節點,其他所有節點都是普通節點。當且僅當主節點故障或與其他節點失去聯繫後,纔會重新選主

Bully 算法在選舉過程中,需要用到以下 3 種消息:

  • Election 消息,用於發起選舉;
  • Alive 消息,對 Election 消息的應答;
  • Victory消息,競選成功的主節點向其他節點發送的宣誓主權的消息。

Bully 算法的具體的選舉過程是:

  • 集羣中每個節點判斷自己的 ID 是否爲當前活着的節點中 ID 最大的,如果是,則直接向其他節點發送 Victory消息,宣誓自己的主權;
  • 如果自己不是當前活着的節點中 ID 最大的,則向比自己 ID 大的所有節點發送 Election消息,並等待其他節點的回覆;
  • 若在給定的時間範圍內,本節點沒有收到其他節點回復的 Alive 消息,則認爲自己成爲主節點,並向其他節點發送Victory 消息,宣誓自己成爲主節點;
  • 若接收到來自比自己 ID 大的節點的 Alive 消息,則等待其他節點發送 Victory消息;
  • 若本節點收到比自己 ID 小的節點發送的 Election 消息,則回覆一個 Alive 消息,告知其他節點,我比你大,重新選舉。
    在這裏插入圖片描述

Bully 應用場景

目前已經有很多開源軟件採用了 Bully 算法進行選主,比如 MongoDB。MongoDB 的分佈式選舉中,採用節點的最後操作時間戳來表示 ID,時間戳最新的節點其 ID 最大,也就是說時間戳最新的、活着的節點是主節點。

Bully 算法小結

Bully 算法的選擇很簡單,就是看誰活着且誰的 ID 最大誰就是主節點,其他節點必須無條件服從。
**優點:**選舉速度快、算法複雜度低、簡單易實現。
**缺點:**需要每個節點有全局的節點信息,因此額外信息存儲較多;其次,任意一個比當前主節點 ID 大的新節點或節點故障後恢復加入集羣的時候,都可能會觸發重新選舉,成爲新的主節點,如果該節點頻繁退出、加入集羣,就會導致頻繁切主。

2.2 Raft 算法

Raft 算法是典型的多數派投票選舉算法,核心思想是:“少數服從多數”,也就是說獲得投票最多的節點成爲主。

** Raft 算法選舉,集羣節點的角色有 3 種:**

  • Leader,即主節點,同一時刻只有一個 Leader,負責協調和管理其他節點;
  • Candidate,即候選者,每一個節點都可以成爲Candidate,節點在該角色下纔可以被選爲新的 Leader
  • Follower,Leader 的跟隨者,不可以發起選舉。

Raft 選舉的流程,可以分爲以下幾步:

  • 初始化時,所有節點均爲 Follower 狀態。
  • 開始選主時,所有節點的狀態由 Follower 轉化爲****Candidate,並向其他節點發送選舉請求。
  • 其他節點根據接收到的選舉請求的先後順序,回覆是否同意成爲主。這裏需要注意的是,在每一輪選舉中,一個節點只能投出一張票。
  • 若發起選舉請求的節點獲得超過一半的投票,則成爲主節點,其狀態轉化爲Leader,其他節點的狀態則由 Candidate 降爲 Follower。Leader 節點與 Follower節點之間會定期發送心跳包,以檢測主節點是否活着。
  • 當 Leader 節點的任期到了,即發現其他服務器開始下一輪選主週期時,Leader節點的狀態由 Leader 降級爲 Follower,進入新一輪選主。
    節點間的狀態轉移如下圖所示:
    節點間的狀態轉移
    注意:每一輪選舉,每個節點只能投一次票
    Raft 算法選主是週期進行的,包括:選主任值兩個時間段,選主階段對應投票階段,任值階段對應節點成爲主之後的任期。但也有例外的時候,如果主節點故障,會立馬發起選舉,重新選出一個主節點。

Raft算法應用場景

Kubernetes 爲了保證可靠性,通常會部署 3 個節點,其中會有一個被選爲主,其他節點作爲備。Kubernetes 的選主採用的是開源的 etcd 組件。而 etcd 就是採用了 Raft 算法來實現選主和一致性的。

Raft算法小結

  • **優點:**具有選舉速度快、算法複雜度低、易於實現;穩定性較比Bully要好,因爲當有新節點加入或節點故障恢復後,會觸發選主,但不一定會真正切主,除非新節點或故障後恢復的節點獲得投票數過半,纔會導致切主。
  • **缺點:**它要求系統內每個節點都可以相互通信,且需要獲得過半的投票數才能選主成功,因此通信量大。

2.3 ZAB 算法

ZAB(ZooKeeper Atomic Broadcast)選舉算法是爲 ZooKeeper 實現分佈式協調功能而設計的。相較於 Raft 算法的投票機制,ZAB 算法增加了通過節點 ID 和數據 ID 作爲參考進行選主,節點 ID 和數據 ID 越大,表示數據越新,優先成爲主。相比較於 Raft 算法,ZAB 算法儘可能保證數據的最新性。所以,ZAB 算法可以說是對 Raft 算法的改進。
使用 ZAB 算法選舉時,集羣中每個節點擁有 3 種角色

  • Leader:主節點;
  • Follower:跟隨者節點;
  • Observer:觀察者,無投票權。
    選舉過程中,集羣中的節點擁有 4 個狀態:
  • Looking 狀態,即選舉狀態。當節點處於該狀態時,它會認爲當前集羣中沒有 Leader,因此自己進入選舉狀
  • Leading狀態,即領導者狀態,表示已經選出主,且當前節點爲 Leader。
  • Following狀態,即跟隨者狀態,集羣中已經選出主後,其他非主節點狀態更新爲 Following,表示對 Leader 的追隨
  • Observing狀態,即觀察者狀態,表示當前節點爲 Observer,持觀望態度,沒有投票權和選舉權。
    投票過程中,每個節點都有一個唯一的三元組 (server_id, server_zxID, epoch),其中 :
  • server_id 表示本唯一的節點ID
  • server_zxID 表示本節點存放的數據 ID,數據 ID 越大表示數據越新,選舉權重越大;
  • epoch 表示當前選取輪數,一般用邏輯時鐘表示。
    ZAB 選舉算法的核心是“:少數服從多數,ID 大的節點優先成爲主”,因此選舉過程中通過 (vote_id, vote_zxID) 來表明投票給哪個節點,其中 vote_id 表示被投票節點的 ID,vote_zxID 表示被投票節點的服務器 zxID。
    ZAB 算法選主的原則是:server_zxID 最大者成爲 Leader;若 server_zxID 相同,則 server_id 最大者成爲 Leader。
    接下來以 3 個 Server節點 的集羣爲例,來介紹 ZAB 選主的過程:
  • 第一步:當系統剛啓動時,3 個服務器當前投票均爲第一輪投票,即 epoch=1,且 zxID 均爲 0。此時每個服務器都推選自己,並將選票信息 廣播出去。
    在這裏插入圖片描述
  • 第二步:根據判斷規則,由於 3 個 Server 的 epoch、zxID 都相同,因此比較 server_id,較大者即爲推選對象,因此 Server 1 和 Server 2 將 vote_id 改爲 3,更新自己的投票箱並重新廣播自己的投票
    在這裏插入圖片描述
  • 第三步:此時系統內所有服務器都推選了 Server 3,因此 Server 3 當選 Leader,處於 Leading 狀態,向其他服務器發送心跳包並維護連接;Server1 和 Server2 處於 Following 狀態。
    在這裏插入圖片描述

ZAB 算法小結

  • 優點:1、ZAB算法性能高,對系統無特殊要求;2、算法選舉穩定性比較好,當有新節點加入或節點故障恢復後,會觸發選主,但不一定會真正切主,除非新節點或故障後恢復的節點數據 ID 和節點 ID 最大,且獲得投票數過半,纔會導致切主
  • 缺點:1、採用廣播方式發送信息,若節點中有 n 個節點,每個節點同時廣播,則集羣中信息量爲 n*(n-1) 個消息,容易出現廣播風暴;2、且除了投票,還增加了對比節點 ID 和數據 ID,這就意味着還需要知道所有節點的 ID 和數據 ID,所以選舉時間相對較長。

3 三種算法總結

在這裏插入圖片描述

4 三種算法思維導圖

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章