難以理解github
Paxos算法是如何工做的?網絡
Paxos算法每一個階段的意圖是什麼?app
很難產生直觀的感覺。分佈式
難以實現並應用於現實中的系統ide
人們在實現Paxos算法時,發現不少實現上的難題,最終開發出和Paxos算法不同的結構。
Raft協議由Diego Ongaro和John Ousterhout(斯坦福大學)共同於2014年設計。
每個服務器存儲着一個日誌序列。每個服務器按照順序應用每條日誌(或稱之爲執行指令),並應用到狀態機中。
保證了日誌序列相同,那麼,在應用每條日誌(或稱之爲執行每一個指令)時,每臺服務器的狀態機狀態都是一致的。
保證日誌序列相同就是一致性算法的工做。
Raft選舉出一個Leader,經過Leader管理日誌複製來實現一致性。
Leader從客戶端接收日誌條目,將日誌條目複製到其餘服務器上。當確保安全性的時候,告訴其餘的服務器應用日誌條目到他們的狀態機上。
爲了可理解性,Raft對經過問題分解,將算法分爲了幾個獨立的部分
Leader選舉
日誌複製
安全性問題
特性 |
解釋 |
---|---|
選舉安全原則 |
對於一個給定的任期號,最多隻會有一個領導人被選舉出來 |
領導人只附加原則 |
領導人絕對不會刪除或者覆蓋本身的日誌,只會增長 |
日誌匹配原則 |
若是兩個日誌在相同的索引位置的日誌條目的任期號相同,那麼咱們就認爲這個日誌從頭到這個索引位置之間所有徹底相同 |
領導人徹底原則 |
若是某個日誌條目在某個任期號中已經被提交,那麼這個條目必然出如今更大任期號的全部領導人中 |
狀態機安全原則 |
若是一個領導人已經在給定的索引值位置的日誌條目應用到狀態機中,那麼其餘任何的服務器在這個索引位置不會提交一個不一樣的日誌 |
一個Raft集羣包含若干個服務器節點,一般是5個,容許整個系統容忍2個節點的失效。
在任什麼時候刻,每個服務期節點都處於如下3種狀態之一:
Leader:處理全部的客戶端請求(若是客戶端將請求發給了Follower,Follower會把請求重定向給Leader)
Follower:不會發送任何請求,只會簡單地響應來自Leader或Candidate的請求
Candidate:用於選舉產生新的領導人
Term——任期
1)每一個任期最多隻能有一個領導人Leader
2)有時候任期內可能沒有領導人(因選舉失敗)
3)每臺機器上維持着當前的任期號。
會在每次RPC通訊時會將本身的任期號進行傳遞(可用於識別過期的信息)
若是RPC收到任期號大的值,變爲follower。
若是RPC收到過時的任期號,返回錯誤信息。
1)每一個機器只能投一次票(含投給本身)
2)得到多數選票的成爲leader
問題:
若是選舉過程當中,一直沒有一個Candidate得到大多數選票,將一直進行重複選舉。
如何保證會有一個Candidate會獲取到大多數選票成爲Leader?
Raft的解決方法:隨機超時時間,保證只有一個follewer超時,變成Candidate,並(在其餘follower超時前)發送投票請求,獲得大多數的選票,從而成爲leader。
客戶端發送命令給Leader。
Leader把日誌條目加到本身的日誌裏。
Leader發送AppendEntries RPC請求給全部的follower。
AppendEntries RPC裏包含着prevLogIndex,prevLogTerm。
Follower接收到後,會檢查相應的日誌條目是否匹配上
1)若是匹配上了(Example#1),將收到的日誌條目添加到本身的日誌裏。
(根據【日誌匹配原則】,表示follower和leader的prevLogIndex之前的全部日誌條目是安全相同的)
2)若是沒有匹配上(Example#2),follower將拒絕這次請求,Leader將index調小,不斷進行重試,直到匹配上。
(Example#3)follower會將後面的日誌條目所有刪除,再將leader的日誌條目添加上。
(日誌提交:指將日誌條目應用到狀態機中)
一旦新的日誌條目變成【已經複製到大多數follower機器上】的了。
(PS:關於上面所講的「大多數follower機器」個數?
問題:能夠這麼理解嗎?
知足【「大多數follower機器」個數 + leader > 集羣中機器個數的一半】就能夠。
好比,集羣中機器個數爲5,「大多數follower機器」個數爲2就能夠了。
答案:
不能夠,由於若是leader宕機不重啓,沒法保證仍舊爲大多數。
)
Leader在狀態機裏提交本身日誌條目,而後返回結果給客戶端
Leader下次發送AppendEntries RPC時,告知follower已經提交的日誌條目信息(lastIndex)
foller收到RPC後,提交到本身的狀態機裏
在Raft運行過程當中,可能的各個機器日誌條目狀態以下。
問題:
領導人S1宕機了,從新進行選舉,是每臺機器均可以被選舉成爲新leader嗎?
若是S4被選舉成term 4的leader,會發生什麼問題?
答案:
當S4發送AppendEntries RPC請求給全部的follower時,
在進行日誌一致性檢查時,會將follower已經提交到狀態機中的日誌條目給刪除掉!!從而違反了狀態機安全原則。
如何保證選舉出的新leader包含全部已提交的日誌條目?
選舉規則的限制:Candidate發送的RequestVote RPC中含有lastIndex,lastTerm。
當機器收到後,若是Candidate的日誌不如本身的新,將拒絕投票給它。
日誌的新舊的比較:經過比較兩份日誌中最後一條日誌條目的索引值和任期號定義誰的日誌比較新。
若是兩份日誌最後的條目的任期號不一樣,那麼任期號大的日誌更加新。
若是兩份日誌最後的條目任期號相同,那麼日誌比較長的那個就更加新。
S1:選票(S1,S2,S3,S4,S5)可得到多數選票
S2:選票(S2,S4)
S3:選票(S1,S2,S3,S4,S5)可得到多數選票
S4:選票(S4)
S5:選票(S2,S4,S5)可得到多數選票
所以,S1, S3, S5可被選舉爲新的leader,S2,S4則不行。
思考:爲什麼經過這種方式能夠保證新選舉的leader必定擁有已commit的日誌條目?
答案:
leader在當日志條目【已經複製到大多數follower機器上】時,纔會提交日誌條目。
假設已經含有已提交日誌條目的機器(可能含上一次的leader)組成的集合爲Set。
根據以上選舉規則的限制,可知新leader必定在Set中。
[1] https://raft.github.io/raft.pdf Raft論文原文
[2] https://github.com/maemual/raft-zh_cn/blob/master/raft-zh_cn.md Raft論文翻譯
[4] https://raft.github.io/ Raft官網
[5] http://thesecretlivesofdata.com/raft/ Raft算法可視化
[6] https://raft.github.io/slides/uiuc2016.pdf
https://www.youtube.com/watch?v=vYp4LYbnnW8&feature=youtu.be
Raft論文做者PPT講稿及視頻