文章目錄
- 一、分布式系統中事務協調的問題
- 二、分布式選舉算法
- 1. Bully算法
- 2. Raft算法
- 3. ZAB算法
- 三、小結與比較
一、分布式系統中事務協調的問題
在分布式系統中,常常有多個節點(應用)共同處理不同的事務和資源。前文
【分布式理論9】分布式協同:分布式系統進程互斥與互斥算法
【分布式理論10】分布式協同:分布式互斥算法最佳實現:分布式鎖的原理與實現
【分布式理論11】分布式協同之分布式事務中介紹了分布式互斥與分布式事務兩類常見問題。分布式互斥問題解決了多個應用訪問同一資源的問題,而分布式事務問題則解決了多個應用訪問不同資源時的一致性問題。解決這些問題的過程中,事務協調者的角色非常重要。事務協調者作為資源訪問的中介,能協調不同節點之間的操作。然而,事務協調者本身的可用性成為了一個不可忽視的問題。
為了增強事務協調者的可用性,通常會使用集群模式,通過主從互備機制來保障事務協調者的持續在線。主節點負責信息的更新,所有從節點負責信息的讀取。若主節點出現故障,系統會通過選舉機制從從節點中選舉出新的主節點,保證系統的正常運行。
?
二、分布式選舉算法
分布式選舉問題的核心在于從一組節點中選舉出一個領導者節點(主節點)。這個過程通常稱為“領導者選舉”。在分布式系統中,確保系統中只有一個領導者是至關重要的,因為只有領導者能夠進行協調和決策。下面將介紹幾種常見的分布式選舉算法。
1. Bully算法
Bully算法的核心思想是從存活的節點中選舉出ID最大(或最小)的節點作為主節點。Bully算法適用于含主從節點的分布式系統,主要通過三種消息類型進行節點間的通信:
- Election消息:發起選舉請求。
- Alive消息:對Election消息的響應。
- Victory消息:競選成功的主節點發送給其他節點,聲明自己為主節點。
在Bully算法中,選舉過程分為以下幾個步驟:
5. 每個節點檢查自己的ID是否為存活節點中最大的,如果是,發送Victory消息宣布自己為主節點。
6. 否則,向比自己ID大的節點發送Election消息,并等待響應。
7. 如果在超時內沒有收到Alive消息,節點認為自己是主節點(會導致腦裂???),發送Victory消息。
8. 如果收到比自己ID大的節點的Alive消息,則放棄競選,等待Victory消息。
這個算法之所以叫"Bully"(欺負人),是因為ID最大的節點通過“欺負”其他節點、強行讓其接受自己為主節點,最終贏得選舉。
舉個例子:假設有4個節點,ID分別為1、2、3、4。如果節點4突然掉線,節點1發現自己沒有收到其他節點的心跳包,就會發起選舉。節點2和節點3的ID都比節點1大,所以節點1會向它們發送選舉消息。節點2和節點3會發出“活躍消息”,讓節點1知道它們不可能成為主節點。最終,節點3會成為新的主節點。
?
2. Raft算法
Raft算法是一種投票選舉算法,遵循“少數服從多數”的原則,規定在一個選舉周期內獲得票數最多的節點為主節點。Raft算法將節點分為三種角色:
- Leader:領導者節點,負責管理和協調其他節點。
- Candidate:候選者節點,具有被選舉為領導者的資格。
- Follower:跟隨者節點,接受領導者的指令,不發起選舉。
Raft算法的選舉過程包括以下步驟:
- 節點角色轉換:在Raft中,所有節點在沒有領導者的情況下,都會是“跟隨者”(Follower)。如果在一定時間內(超時)沒有收到領導者的心跳包,跟隨者會自愿變為“候選者”(Candidate),開始發起選舉。
- 選舉過程:當一個節點變為候選者時,它會向其他所有節點發起選舉請求。如果一個節點的選舉請求得到了大多數節點的投票支持,它就會成為領導者(Leader)。此時,其他節點會變回“跟隨者”角色,開始接受領導者的指揮。
- 選舉的勝者:如果有多個候選者同時發起選舉,系統會出現“選舉超時”,導致選舉周期重復進行,直到某一個候選者最終獲得超過半數節點的投票支持,成為領導者。
- 選舉超時與心跳機制:選舉是基于超時控制的。在Raft中,選舉超時是隨機的,防止多個節點同時發起選舉。選舉超時到達后,節點會開始投票,直到某個候選者得到過半數支持。
- 領導者的責任:當一個節點成為領導者時,它需要定期向所有跟隨者發送“心跳包”(Heartbeat)。如果在選舉超時內,跟隨者沒有收到領導者的心跳包,它們會再次發起選舉。這是為了確保領導者一直在系統中活動,保證整個系統的穩定性。
- 領導者失敗后的恢復:如果領導者失敗,系統會重新啟動選舉過程,選舉新的領導者,確保系統始終能繼續工作。
如果領導者發生故障,或者網絡出現分區,選舉過程會重新啟動,確保集群內總是有一個領導者。Raft算法中的“日志復制”機制可以保證數據的一致性,通過將客戶端的操作記錄到日志中,領導者向跟隨者同步日志,并等待確認,直到達到多數節點的確認,領導者才會提交該操作。
?
舉個例子:假設有5個節點(ID分別為A、B、C、D、E),初始時A是領導者。如果A節點由于故障未能發送心跳包,B、C、D、E會感知到沒有收到心跳包,開始選舉過程。B、C和D可能會同時成為候選者,最終一個候選者(比如B)會獲得超過半數的選票,成為新的領導者。
?
3. ZAB算法
ZAB(ZooKeeper Atomic Broadcast)算法是專為ZooKeeper設計的一種協議,目的是保證集群中數據的一致性。ZAB算法通過將集群中的事務請求轉化為提議,并通過廣播方式同步到集群中的所有節點,來保證數據一致性。ZAB算法的選舉過程類似于Raft算法,但有其獨特的實現方式。ZAB算法的選舉過程包括四種狀態:
原理:
- 角色劃分:ZAB將節點分為四種角色:
- 領導者(Leader):負責處理所有客戶端請求并將請求轉換成提議(Proposal),然后廣播給集群中的所有跟隨者。
- 跟隨者(Follower):接受領導者的提議,進行確認,并按照領導者的日志進行操作。
- 觀察者(Observer):類似于跟隨者,但不參與選舉和日志同步,它只是觀測集群的狀態。
- Looking狀態:當集群中沒有領導者時,所有節點都進入該狀態,開始選舉新領導者。
- 選舉過程:ZAB的選舉是通過一個三元組(ServerID, ZXID, epoch)來確定領導者。每個節點都維護自己的事務ID(ZXID)和選舉輪次(epoch)。ZAB算法的選舉規則是:節點通過比較ZXID來決定誰是領導者。如果ZXID相同,則比較節點的ServerID,選擇ID最大的節點作為領導者。
- 數據一致性:ZAB通過廣播機制來確保數據的一致性。每個事務請求被轉化為提議,并由領導者廣播給所有跟隨者。只有當超過半數的跟隨者確認提議時,領導者才會提交提議,確保所有節點的數據一致。
在選舉過程中,ZAB算法使用三元組信息(ServerID, ZXID, epoch)來確定領導者。選舉規則是:首先比較ZXID,選擇ZXID最大的節點作為領導者;如果ZXID相同,則選擇ServerID較大的節點。
?
三、小結與比較
Bully、Raft與ZAB算法各自具有不同的特點和適用場景:
- Bully算法:通過簡單的ID比較選舉出主節點,最大ID的節點最終成為主節點。適用于節點間連接良好的場景,但可能在節點數量多時效率較低。
- Raft算法:通過投票選舉方式確保選舉的公平性,候選者必須獲得超過半數節點的支持才能成為領導者,適合高可用性和一致性要求高的系統。
- ZAB算法:針對ZooKeeper等高可用分布式系統設計,通過廣播機制和事務提議確保數據一致性,適用于需要強一致性保證的系統。
這三種算法在解決分布式系統中選舉問題的同時,也對提高系統的可用性與一致性起到了關鍵作用。通過選舉機制,能夠確保在事務協調者不可用時,系統能夠迅速選舉出新的協調者,保證系統的持續運行。
?
參考:《分布式架構原理與實踐-崔皓》