Raft共识算法
前提條件
Raft不考慮拜庭將軍問題,即消息會延遲、丟失但不會錯誤。
Raft的特性
- Strong leader:在 Raft 中,日志條目(log entries)只從 leader 流向其他服務器。 這簡化了復制日志的管理,使得 raft 更容易理解。
- Leader 選舉:Raft 使用隨機計時器進行 leader 選舉。 這只需在任何一致性算法都需要的心跳(heartbeats)上增加少量機制,同時能夠簡單快速地解決沖突。
- 成員變更:Raft 使用了一種新的聯合一致性方法,其中兩個不同配置的大多數在過渡期間重疊。 這允許集群在配置更改期間繼續正常運行。
通過選舉一個 leader 的方式,Raft 將一致性問題分解成了三個相對獨立的子問題:
- Leader 選舉:當前的 leader 宕機時,一個新的 leader 必須被選舉出來。(5.2 節)
- 日志復制:Leader 必須從客戶端接收日志條目然后復制到集群中的其他節點,并且強制要求其他節點的日志和自己的保持一致。
- 安全性:Raft 中安全性的關鍵是圖 3 中狀態機的安全性:如果有任何的服務器節點已經應用了一個特定的日志條目到它的狀態機中,那么其他服務器節點不能在同一個日志索引位置應用一條不同的指令。章節 5.4 闡述了 Raft 算法是如何保證這個特性的;該解決方案在選舉機制(5.2 節)上增加了額外的限制。
Raft算法的RPC和設置
Raft 算法中服務器節點之間通信使用遠程過程調用(RPCs),并且基本的一致性算法只需要兩種類型的 RPCs。
RPC有三種:
超時設置:
BroadcastTime << ElectionTimeout << MTBF
兩個原則:
一般BroadcastTime大約為0.5毫秒到20毫秒,ElectionTimeout一般在10ms到500ms之間。大多數服務器的MTBF都在幾個月甚至更長。
Leader選舉
一個 Raft 集群包含若干個服務器節點;通常是 5 個,這樣的系統可以容忍 2 個節點的失效。在任何時刻,每一個服務器節點都處于這三個狀態之一:leader、follower 或者 candidate 。在正常情況下,集群中只有一個 leader 并且其他的節點全部都是 follower 。
- Follower 都是被動的:他們不會發送任何請求,只是簡單的響應來自 leader 和 candidate 的請求。
- Leader: 處理所有的客戶端請求(如果一個客戶端和 follower 通信,follower 會將請求重定向給 leader)。
- candidate: 用來選舉一個新的 leader
Raft 把時間分割成任意長度的任期(term),如圖 5 所示。任期用連續的整數標記。每一段任期從一次選舉開始,一個或者多個 candidate 嘗試成為 leader 。
如果一個服務器的當前任期號比其他的小,該服務器會將自己的任期號更新為較大的那個值。如果一個 candidate 或者 leader 發現自己的任期號過期了,它會立即回到 follower 狀態。如果一個節點接收到一個包含過期的任期號的請求,它會直接拒絕這個請求。
Leader選舉過程
Raft 使用一種心跳機制(每個節點都維護一個隨機時鐘)來觸發 leader 選舉。當服務器程序啟動時,他們都是 follower 。一個服務器節點只要能從 leader 或 candidate 處接收到有效的 RPC 就一直保持 follower 狀態。Leader 周期性地向所有 follower 發送心跳(不包含日志條目的 AppendEntries RPC)來維持自己的地位。
觸發條件:
候選操作過程:
追隨者自增當前任期,轉換為Candidate,對自己投票,并發起RequestVote RPC,等待下面三種情形發生;
注意事項:
日志復制
只要過半的服務器能正常運行,Raft 就能夠接受,復制并應用新的日志條目;在正常情況下,新的日志條目可以在一個 RPC 來回中被復制給集群中的過半機器;并且單個運行慢的 follower 不會影響整體的性能。
Leader接受命令的過程:
提交過程:
安全性(保證日志順序)
到目前為止描述的機制并不能充分的保證每一個狀態機會按照相同的順序執行相同的指令。
為了保證安全性增加以下限制:
1. 領導者追加日志(Append-Only)
領導者永遠不會覆蓋已經存在的日志條目;
日志永遠只有一個流向:從領導者到追隨者;
2. 選舉限制:投票阻止沒有全部日志條目的服務器贏得選舉
如果投票者的日志比候選人的新,拒絕投票請求;
這意味著要贏得選舉,候選者的日志至少和大多數服務器的日志一樣新,那么它一定包含全部的已經提交的日志條目。
3. 永遠不提交任期之前的日志條目(只提交任期內的日志條目)
在Raft算法中,當一個日志被安全的復制到絕大多數的機器上面,即AppendEntries RPC在絕大多數服務器正確返回了,那么這個日志就是被提交了,然后領導者會更新commit index。
總結
Raft明確了集群的功能+集群的實現細節。所有角色都可以接收用戶請求,leader對所有的讀寫請求負責,也就是說,只有leader對最終的讀寫有解釋權。通過這可以了解到,raft承擔的是強一致性場景,其讀和寫其實是差不多的過程,不會存在讀比寫快。那么follower如果接收到請求會會怎么辦呢?會進行請求轉發,這樣會多增加一些rpc的請求。
Raft集群將工作狀態分成兩種,一種是日志復制,另一種是領導選舉。其中領導選舉是一種不穩定的狀態,在這種不穩定的狀態中,會出現數據安全、成員狀態變更等問題。另外一種日志復制是一種穩定狀態,在leader確定的情況下,leader指導所有機器按規定來完成數據的讀寫要求,其中規定包括如下:
參考
- Raft論文翻譯
- Raft一致性算法筆記
- Raft演示動畫
- Raft算法總結
總結
- 上一篇: (linux struct)
- 下一篇: 香港域名注册怎么绑定ip(如何注册香港域