最近工作中討論到了raft協議相關的一些問題,正好之前讀過多次raft協議的那*****,所以趁著討論做一次總結整理。
我會將raft協議拆成四個部分去總結:
演算法基礎
選舉和日誌複製
安全性節點變更
這是第一篇:《解讀raft(一 演算法基礎)》
分布式系統除了提公升整個體統的效能外還有乙個重要特徵就是提高系統的可靠性。
提供可靠性可以理解為系統中一台或多台的機器故障不會使系統不可用(或者丟失資料)。
保證系統可靠性的關鍵就是多副本(即資料需要有備份),一旦有多副本,那麼久面臨多副本之間的一致性問題。
一致性演算法正是用於解決分布式環境下多副本之間資料一致性的問題的。
業界最著名的一致性演算法就是大名鼎鼎的paxos(chubby的作者曾說過:世上只有一種一致性演算法,就是paxos)。但paxos是出了名的難懂,而raft正是為了探索一種更易於理解的一致性演算法而產生的。
raft is a consensus algorithm for managing a replicated log.raft是一種管理複製日誌的一致性演算法。
它的首要設計目的就是易於理解,所以在選主的衝突處理等方式上它都選擇了非常簡單明瞭的解決方案。
raft將一致性拆分為幾個關鍵元素:
所有一致性演算法都會涉及到狀態機,而狀態機保證系統從乙個一致的狀態開始,以相同的順序執行一些列指令最終會達到另乙個一致的狀態。
以上是狀態機的示意圖。所有的節點以相同的順序處理日誌,那麼最終x、y、z的值在多個節點中都是一致的。
演算法基礎
角色
raft通過選舉leader並由leader節點負責管理日誌複製來實現多副本的一致性。
在raft中,節點有三種角色:
角色轉換如下圖所示:
任期
raft把時間切割為任意長度的任期,每個任期都有乙個任期號,採用連續的整數。
每個任期都由一次選舉開始,若選舉失敗則這個任期內沒有leader;如果選舉出了leader則這個任期內有leader負責集群狀態管理。
演算法
狀態
狀態所有節點上持久化的狀態(在響應rpc請求之前變更且持久化的狀態)
currentterm
伺服器的任期,初始為0,遞增
votedfor
在當前獲得選票的候選人的 id
log日誌條目集;每乙個條目包含乙個使用者狀態機執行的指令,和收到時的任期號
狀態所有節點上非持久化的狀態
commitindex
最大的已經被commit的日誌的index
最大的已經被應用到狀態機的index
狀態leader節點上非持久化的狀態(選舉後重新初始化)
nextindex
每個節點下一次應該接收的日誌的index(初始化為leader節點最後乙個日誌的index + 1)
matchindex
每個節點已經複製的日誌的最大的索引(初始化為0,之後遞增)
用於leader節點複製日誌給其他節點,也作為心跳。
引數解釋
term
leader節點的任期
leaderid
leader節點的id
prevlogindex
此次追加請求的上乙個日誌的索引
prevlogterm
此次追加請求的上乙個日誌的任期
entries
追加的日誌(空則為心跳請求)
leadercommit
leader上已經commit的index
prevlogindex和prevlogterm表示上一次傳送的日誌的索引和任期,用於保證收到的日誌是連續的。
返回值解釋
term
當前任期號,用於leader節點更新自己的任期(應該說是如果這個返回值比leader自身的任期大,那麼leader需要更新自己的任期)
success
如何follower節點匹配prevlogindex和prevlogterm,返回true
接收者實現邏輯
返回false,如果收到的任期比當前任期小
返回false,如果不包含之前的日誌條目(沒有匹配prevlogindex和prevlogterm)
如果存在index相同但是term不相同的日誌,刪除從該位置開始所有的日誌
追加所有不存在的日誌
如果leadercommit>commitindex,將commitindex設定為commitindex = min(leadercommit, index of last new entry)
requestvote rpc
用於candidate獲取選票。
引數解釋
term
candidate的任期
candidateid
candidate的id
lastlogindex
candidate最後一條日誌的索引
lastlogterm
candidate最後一條日誌的任期
引數解釋
term
當前任期,用於candidate更新自己的任期
votegranted
true表示給candidate投票
接收者的實現邏輯
返回false,如果收到的任期比當前任期小
如果本地狀態中votedfor為null或者candidateid,且candidate的日誌等於或多餘(按照index判斷)接收者的日誌,則接收者投票給candidate,即返回true
節點的執行規則
所有節點
如果rpc請求或者響應包含的任期t > currentterm,將currentterm設定為t並轉換為follower
followers
candidates
如果收到了大多數節點的選票,轉換為leader節點
如果選舉超時,重新開始新一輪的選舉
演算法導論 一 演算法基礎
迴圈不變式主要用來幫助我們理解程式的正確性。迴圈不變式的三條性質 初始化 迴圈的第一次迭代之前,它為真。保持 如果迴圈的某次迭代之前它為真,那麼下次迭代之前它仍為真。終止 再迴圈終止時,可驗證演算法的正確性。偽 的重要性在於它可以簡潔地表達出演算法的本質 縮排代表塊結構 採用縮排代表塊結構可以大大提...
(一)演算法基礎 排序演算法
作為演算法的入門,排序演算法再合適不過了,在這裡我主要介紹四種排序演算法 插入排序 歸併排序 快速排序以及希爾排序。不過在介紹這些演算法之前,我們先來做一些準備工作。一 演算法測試函式 在實現乙個演算法後,必然要對這個演算法進行除錯和分析,這裡我寫了一些函式用於演算法的測試。隨機數組生成函式 int...
基礎演算法之一 演算法概論
常見的基礎演算法有 分治 動態規劃 貪心 回溯與分支限界等,常用的技巧方法有 遞迴,遞推,空間時間互換,快取,重疊子問題,記憶化。演算法的本質是 狀態,狀態的轉移,問題的定義,以及子問題的定義。分治演算法思想 分而治之,大事化小小事化了。一句話 化繁為簡。例子 快排。動態規劃思想 由前乙個或者幾個狀...