一文理解 Raft 分佈式一致性算法

一、Raf 算法背景

在學術理論界,分佈式一致性算法的代表還是 Paxos。但是少數理解的人覺得很簡單,尚未理解的覺得很難,大多數人還是一知半解。Paxos 的可理解性和工程落地性的門檻很高。斯坦福學者也花了很多時間理解 Paxos,於是他們又研究出 Raft。

二、Raft 算法基本原理

共識算法就是保證一個集羣的多臺機器協同工作,在遇到請求時,數據能夠保持一致。即使遇到機器宕機,整個系統仍然能夠對外保持服務的可用性

Raft 將共識問題分解三個子問題:

所以,Raft 算法核心流程可以歸納爲:

這裏先介紹一下日誌同步的概念:服務器接收客戶的數據更新 / 刪除請求,這些請求會落地爲命令日誌。只要輸入狀態機的日誌命令相同,狀態機的執行結果就相同。所以 Raft 的核心就是 leader 發出日誌同步請求,follower 接收並同步日誌,最終保證整個集羣的日誌一致性。

1. Leader Election 領導選舉

集羣中每個節點只能處於 Leader、Follower 和 Candidate 三種狀態的一種:

(1)follower 從節點:

(2)candidate 候選者:

(3)leader 主節點:

具體的節點狀態轉換參考下圖:

Raft 算法把時間軸劃分爲不同任期 Term。每個任期 Term 都有自己的編號 TermId,該編號全局唯一且單調遞增。如下圖,每個任務的開始都 Leader Election 領導選舉。如果選舉成功,則進入維持任務 Term 階段,此時 leader 負責接收客戶端請求並,負責複製日誌。Leader 和所有 follower 都保持通信,如果 follower 發現通信超時,TermId 遞增併發起新的選舉。如果選舉成功,則進入新的任期。如果選舉失敗,TermId 遞增,然後重新發起選舉直到成功。

舉個例子,參考下圖,Term N 選舉成功,Term N+1 和 Term N+2 選舉失敗,Term N+3 重新選舉成功。

具體的說,Leader 在任期內會週期性向其他 follower 節點發送心跳來維持地位。follower 如果發現心跳超時,就認爲 leader 節點宕機或不存在。隨機等待一定時間後,follower 會發起選舉,變成 candidate,然後去競選 leader。選舉結果有三種情況:

(1)獲取超過半數投票,贏得選舉:

(2)投票未超過半數,選舉失敗:

(3)收到其他 Leader 通信請求:

簡單地說,Leader Election 領導選舉通過若干的投票原則,保證一次選舉有且僅可能最多選出一個 leader,從而解決了腦裂問題

2. Log Replication 日誌複製

選舉 leader 成功後,整個集羣就可以正常對外提供服務了。Leader 接收所有客戶端請求,然後轉化爲 log 複製命令,發送通知其他節點完成日誌複製請求。每個日誌複製請求包括狀態機命令 & 任期號,同時還有前一個日誌的任期號和日誌索引。狀態機命令表示客戶端請求的數據操作指令,任期號表示 leader 的當前任期。

follower 收到日誌複製請求的處理流程:

(1)follower 會使用前一個日誌的任期號和日誌索引來對比自己的數據:

(2)leader 收到拒絕複製的回覆後,繼續發送節點日誌複製請求,不過這次會帶上更前面的一個日誌任期號和索引;

(3)如此循環往復,直到找到一個共同的任期號 & 日誌索引。此時 follower 從這個索引值開始複製,最終和 leader 節點日誌保持一致;

(4)日誌複製過程中,Leader 會無限重試直到成功。如果超過半數的節點複製日誌成功,就可以任務當前數據請求達成了共識,即日誌可以 commite 提交了;

綜上,Log Replication 日誌複製有兩個特點:

(1)如果在不同日誌中的兩個條目有着相同索引和任期號,則所存儲的命令是相同的,這點是由 leader 來保證的;

(2)如果在不同日誌中的兩個條目有着相同索引和任期號,則它們之間所有條目完全一樣,這點是由日誌複製的規則來保證的;

舉個例子,最上面表示日誌索引,這個是保證唯一性。每個方塊代表指定任期內的數據操作,目前來看,LogIndex 1-4 的日誌已經完成同步,LogIndex 5 的正在同步,LogIndex6 還未開始同步。Raft 日誌提交的過程有點類似兩階段原子提交協議 2PC,不過和 2PC 的最大區別是,Raft 要求超過一般節點同意即可 commited,2PC 要求所有節點同意才能 commited。

日誌不一致問題:在正常情況下,leader 和 follower 的日誌複製能夠保證整個集羣的一致性,但是遇到 leader 崩潰的時候,leader 和 follower 日誌可能出現了不一致的狀態,此時 follower 相比 leader 缺少部分日誌。

爲了解決數據不一致性,Raft 算法規定 follower 強制複製 leader 節日的日誌,即 follower 不一致日誌都會被 leader 的日誌覆蓋,最終 follower 和 leader 保持一致。簡單的說,從前向後尋找 follower 和 leader 第一個公共 LogIndex 的位置,然後從這個位置開始,follower 強制複製 leader 的日誌。但是這麼多還有其他的安全性問題,所以需要引入 Safety 安全性規則。

3. Safety 安全性

當前的 Leader election 領導選舉和 Log replication 日誌複製並不能保證 Raft 算法的安全性,在一些特殊情況下,可能導致數據不一致,所以需要引入下面安全性規則。

(1)Election Safety 選舉安全性:避免腦裂問題

選舉安全性要求一個任期 Term 內只能有一個 leader,即不能出現腦裂現象,否者 raft 的日誌複製原則很可能出現數據覆蓋丟失的問題。Raft 算法通過規定若干投票原則來解決這個問題:

(2)Leader Append-Only 日誌只能由 leader 添加修改

Raft 算法規定,所有的數據請求都要交給 leader 節點處理,要求:

(3)Log Matching 日誌匹配特性

這點主要是爲了保證日誌的唯一性,要求:

(4)Leader Completeness 選舉完備性:leader 必須具備最新提交日誌

Raft 規定:只有擁有最新提交日誌的 follower 節點纔有資格成爲 leader 節點。具體做法:candidate 競選投票時會攜帶最新提交日誌,follower 會用自己的日誌和 candidate 做比較。

因爲日誌提交需要超過半數的節點同意,所以針對日誌同步落後的 follower(還未同步完全部日誌,導致落後於其他節點)在競選 leader 的時候,肯定拿不到超過半數的票,也只有那些完成同步的纔有可能獲取超過半數的票成爲 leader。

日誌更新判斷方式是比較日誌項的 term 和 index:

下面舉個例子來解釋爲什麼需要這個原則,如下圖,假如集羣中 follower4 在 LogIndex3 故障宕機,經過一段時間間,任期 Term3 的 leader 接收並提交了很多日誌(LogIndex1-5 已經提交,LogIndex6 正在複製中)。然後 follower4 恢復正常,在沒有和 leader 完成同步日誌的情況下,如果 leader 突然宕機,此時開始領導選舉。再假設在 Term4 follower4 當選 leader。根據日誌複製的規則,其他 follower 強制複製 leader 的日誌,那麼已經提交卻沒完成同步的日誌將會被強制覆蓋掉,這回導致已提交日誌被覆蓋。

(5)State Machine Safety 狀態機安全性:確保當前任期日誌提交

考慮到當前的日誌複製規則:

上述兩條就可能出現已有任期日誌被覆蓋的情況,這意味着已複製超過半數的以前任期日誌被強制覆蓋了,和前面提到的日誌安全性矛盾。

所以,Raft 對日誌提交有額外安全機制:leader 只能提交當前任期 Term 的日誌,舊任期 Term(以前的數據)只能通過當前任期 Term 的數據提交來間接完成提交。簡單的說,日誌提交有兩個條件需要滿足:

下面舉個例子來解釋爲什麼需要這個原則,如下圖:

如何解決這個問題呢?Raft 在日誌項提交上增加了限制:只有當前任期且複製超過半數的日誌纔可以提交。即只有 LogIndex4 提交後,LogIndex3 纔會被提交。

三、Paxos VS Raft

這個世界上只有一種一致性算法,那就是 Paxos。

Basic Paxos 算法沒有 leader proposer 角色,是一個純粹的去中心化的分佈式算法,但是它存在若干不足(只能單值共識 & 活鎖 & 網絡開銷大)。所以纔有了以 leader proposer 爲核心的 Multi Paxos 算法(由一個去中心化的算法變爲 leader-based 的算法)。Raft 算法相當於 Multi Paxos 的進一步優化,主要通過增加兩個限制:

(1)日誌添加次序性:

(2)選主限制:

下面是我個人的理解:

四、總結

學習總結分佈式一致性算法 Paxos 和 Raft 對我們理解、設計、實現、部署、測試分佈式系統都大有益處,希望本文能與大家共同商榷。

作者簡介

張輝,騰訊後臺開發工程師,主要負責騰訊霧計算平臺 PCDN SDK 相關的業務,畢業於南京大學計算機系。

推薦關注「數據分析與開發」,提升數據技能

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/HZ728ylDsa4U6qY_hvKsZQ