raft算法与paxos算法相比有什么优势,使用场景有什么差异?
Raft協議比paxos的優點是 容易理解,容易實現。它強化了leader的地位,把整個協議可以清楚的分割成兩個部分,并利用日志的連續性做了一些簡化:(1)Leader在時。由Leader向Follower同步日志(2)Leader掛掉了,選一個新Leader,Leader選舉算法。
但是本質上來說,它容易的地方在于流程清晰,描述更清晰,關鍵之處都給出了偽代碼級別的描述,可以直接用于實現,而paxos最初的描述是針對非常理論的一致性問題,真正能應用于工程實現的mulit-paxos,Lamport老爺爺就提了個大概,之后也有人嘗試對multi-paxos做出更為完整詳細的描述,但是每個人描述的都不大一樣。
Zookeeper的ZAB,Viewstamped Replication(VR),raft,multi-paxos,這些都可以被稱之為Leader-based一致性協議。不同的是,multi-paxos leader是作為對經典paxos的優化而提出,通過選擇一個proposer作為leader降低多個proposer引起沖突的頻率,合并階段一從而將一次決議的平均消息代價縮小到最優的兩次,實際上就算有多個leader存在,算法還是安全的,只是退化為經典的paxos算法。而經典的paxos,從一個提案被提出到被接受分為兩個階段,第一個階段去詢問值,第二階段根據詢問的結果提出值。這兩個階段是無法分割的,兩個階段的每個細節都是精心設計的,相互關聯,共同保障了協議的一致性。而VR,ZAB,Raft這些強調合法leader的唯一性協議,它們直接從leader的角度描述協議的流程,也從leader的角度出發論證正確性。但是實際上它們使用了和Paxos完全一樣的原理來保證協議的安全性,當同時存在多個節點同時嘗試成為leader或者不知一個節點認為自己時leader時,本質上它們和經典Paxos中多個proposer并存的情形沒什么不同。
Paxos和raft都是一旦一個entries(raft協議叫日志,paxos叫提案,叫法而已)得到多數派的贊成,這個entries就會定下來,不丟失,值不更改,最終所有節點都會贊成它。Paxos中稱為提案被決定,Raft,ZAB,VR稱為日志被提交,這只是說法問題。一個日志一旦被提交(或者決定),就不會丟失,也不可能更改,這一點這4個協議都是一致的。Multi-paxos和Raft都用一個數字來標識leader的合法性,multi-paxos中叫proposer-id,Raft叫term,意義是一樣的,multi-paxos proposer-id最大的Leader提出的決議才是有效的,raft協議中term最大的leader才是合法的。實際上raft協議在leader選舉階段,由于老leader可能也還存活,也會存在不只一個leader的情形,只是不存在term一樣的兩個leader,因為選舉算法要求leader得到同一個term的多數派的同意,同時贊同的成員會承諾不接受term更小的任何消息。這樣可以根據term大小來區分誰是合法的leader。Multi-paxos的區分leader的合法性策略其實是一樣的,誰的proproser-id大誰合法,而proposer-id是唯一的。因此它們其實在同一個時刻,都只會存在一個合法的leader。同時raft協議的Leader選舉算法,新選舉出的Leader已經擁有全部的可以被提交的日志,而multi-paxos擇不需要保證這一點,這也意味multi-paxos需要額外的流程從其它節點獲取已經被提交的日志。因此raft協議日志可以簡單的只從leader流向follower在raft協議中,而multi-paxos則需要額外的流程補全已提交的日志。需要注意的是日志可以被提交和日志已經被提交是兩個概念,它們的區別就像是我前方有塊石頭和我得知我前方有塊石頭。但是實際上,Raft和multi-Paxos一旦日志可以被提交,就能會保證不丟失,multi-paxos天然保證了這一點,這也是為什么新leader對于尚未被確認已經提交的日志需要重新執行經典paxos的階段一,來補全可能缺失的已經被提交的日志,Raft協議通過強制新Leader首先提交一個本term的no-op 日志,配合前面提到的Leader選舉算法所保證的性質,確保了這一點。一條日志一旦被多數派的節點寫入本地日志文件中,就可以被提交,但是leader只有得知這一點后,才會真正commit這條日志,此時日志才是已經被提交的。
Raft協議強調日志的連續性,multi-paxos則允許日志有空洞。日志的連續性蘊含了這樣一條性質:如果兩個不同節點上相同序號的日志,只要term相同,那么這兩條日志必然相同,且這和這之前的日志必然也相同的,這使得leader想follower同步日志時,比對日志非常的快速和方便;同時Raft協議中日志的commit(提交)也是連續的,一條日志被提交,代表這條日志之前所有的日志都已被提交,一條日志可以被提交,代表之前所有的日志都可以被提交。日志的連續性使得Raft協議中,知道一個節點的日志情況非常簡單,只需要獲取它最后一條日志的序號和term??梢耘e個列子,A,B,C三臺機器,C是Leader,term是3,A告訴C它們最后一個日志的序列號都是4,term都是3,那么C就知道A肯定有序列號為1,2,3,4的日志,而且和C中的序列號為1,2,3,4的日志一樣,這是raft協議日志的連續性所強調的,好了那么Leader知道日志1,2,3,4已經被多數派(A,C)擁有了,可以提交了。同時,這也保證raft協議在leader選舉的時候,一個多數派里必然存在一個節點擁有全部的已提交的日志,這是由于最后一條被commit的日志,至少被多數派記錄,而由于日志的連續性,擁有最后一條commit的日志也就意味著擁有全部的commit日志,即至少有一個多數派擁有所有已commit的日志。并且只需要從一個多數集中選擇最后出最后一條日志term最大且序號最大的節點作為leader,新leader必定是擁有全部已commit的日志(關于這一點的論證,可以通過反證法思考一下,多數集中節點A擁有最后一條已commit的日志,但是B沒有,而B當選leader。根據選主的法則只能有兩種可能(1)當選而A最后一條日志的term小于B;(2)A最后一條日志的term等于B,但是A的日志少于B。1,2可能嘛?)而對于multi-paxos來說,日志是有空洞的,每個日志需要單獨被確認是否可以commit,也可以單獨commit。因此當新leader產生后,它只好重新對每個未提交的日志進行確認,已確定它們是否可以被commit,甚至于新leader可能缺失可以被提交的日志,需要通過Paxos階段一向其它節點學習到缺失的可以被提交的日志,當然這都可以通過向一個多數派詢問完成(這個流程存在著很大的優化空間,例如可以將這個流程合并到leader選舉階段,可以將所有日志的確認和學習合并到一輪消息中,減少消息數目等)。但是無論是Raft還是multi-paxos,新leader對于那些未提交的日志,都需要重新提交,不能隨意覆寫,因為兩者都無法判定這些未提交的日志是否已經被之前的leader提交了。所以本質上,兩者是一樣的。一個日志被多數派擁有,那么它就可以被提交,但是Leader需要通過某種方式得知這一點,同時為了已經被提交的日志不被新leader覆寫,新leader需要擁有所有已經被提交的日志(或者說可以被提交,因為有時候并沒有辦法得知一條可以被提交的日志是否已經被提交,例如當只有老leader提交了該日志,并返回客戶端成功,然而老leader掛了),之后才能正常工作,并且需要重新提交所有未commit的日志。兩者的區別在于Leader確認提交和獲取所有可以被提交日志的方式上,而方式上的區別又是由于是日志是否連續造成的,Raft協議利用日志連續性,簡化了這個過程。
在Raft和multi-paxos協議確保安全性的原理上,更進一步的說,所有的凡是 滿足 集群中存活的節點數還能構成一個多數派,一致性就能滿足的算法,raft協議,paxos,zab,viewstamp都是利用了同一個性質:兩個多數派集合之間存在一個公共成員。對于一致性協議來說,一旦一個變量的值被確定,那么這個變量的值應該是唯一的,不再更改的。Raft,paoxos等協議,對于一個變量v來說,一個由節點n1提出的值a只有被一個多數集q1認可并記錄后,才會正式令v=a,如果另一個節點n2想要修改變量v的值為b,也需要一個多數集q2的認可,而q1和q2必然至少有一個共同的成員p,節點p已經記錄了v=a。因此只需要通過增加一些約束,讓p能夠告訴節點n2這個事實:v=a,使得n2放棄自己的提議,或者讓節點p拒絕節點n2想要賦予v的值為b這個行為,都可以確保變量v的一致性不被破壞。這個思想對于這個四個協議來說都是一樣的,4個協議都使用一個唯一的整數作為標識符來標明leader的合法性,paxos叫做proposer-id,ZAB叫epoch,VR叫view,raft叫term。把leader看做是想要賦予變量v某個值的節點n1,n2,上面提到的情形中,如果n2是目前的合法leader,那么n2需要知道v=a這個事實,對于raft來說就是選擇n2是已經記錄了v=a的節點,對于multi-paxos來說,就是重新確認下v的值。如果n1是目前的合法leader,n2是老的leader,p就會根據leader的標識符拒絕掉n2的提案,n2的提案會由于得不到一個多數派的接受而失效。最直接的從理論上闡明這個原理的是經典的paxos算法,關于這個原理更具體的闡述可以看看我在如何淺顯易懂地解說 Paxos 的算法?下的回答。所以確實在一定程度上可以視raft,ZAB,VR都是paxos算法的一種改進,一種簡化,一種優化,一種具象化。Lamport老人家還是最具思想和代表的,不過值得一提的是,ZAB和raft作者確實是受了paxos很多啟發,VR是幾乎同時獨立于paxos提出的。
Raft容易實現在于它的描述是非常規范的,包括了所有的實現細節。如上面的人說的有如偽代碼。而paxos的描述側重于理論,工程實現按照谷歌chubby論文中的說話,大家從paxos出現,寫著寫著,處理了n多實際中的細節之后,已經變成另外一個算法了,這時候正確性已經無法得到理論的保證。所以它的實現非常難,因為一致性協議實非常精妙的。小細節上沒考慮好,整個協議的一致性就崩潰了,而發現并更正細節上的錯誤在沒有詳盡的現成的參考的情況下是困難的,這需要對協議很深的理解。而且在Raft協議的博士論文CONSENSUS: BRIDGING THEORY AND PRACTICE,兩位作者手把手事無巨細的教你如何用raft協議構建一個復制狀態機。我表示智商正常的大學生,都能看懂。我相信在未來一致性現在被提起來,肯定不是現在這樣,大部分人覺得好難啊,實現更難。但是未來其應該會成為一種常用技術。
總結
以上是生活随笔為你收集整理的raft算法与paxos算法相比有什么优势,使用场景有什么差异?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flash 3.6如何利用遮罩打造照片焦
- 下一篇: session 和cookie的理解