Paxos和Raft的前世今生
在保證數(shù)據(jù)安全的基礎(chǔ)上,保持服務(wù)的持續(xù)可用,是核心業(yè)務(wù)對底層數(shù)據(jù)存儲系統(tǒng)的基本要求。業(yè)界常見的1主N備的方案面臨的問題是“最大可用(Maximum Availability)”和“最大保護(hù)(Maximum Protection)”模式間的艱難抉擇:
“最大可用”模式,表示主機盡力將數(shù)據(jù)同步到備機之后才返回成功,如果備機宕機或網(wǎng)絡(luò)中斷那么主機則單獨提供服務(wù),這意味著主備都宕機情況下可能的數(shù)據(jù)丟失(MySQL的半同步模式);
“最大保護(hù)”模式,表示主機一定要將數(shù)據(jù)同步到備機后才能返回成功,則意味著在任意備機宕機或網(wǎng)絡(luò)中斷情況下主機不得不停服務(wù)等待備機或網(wǎng)絡(luò)恢復(fù)(MySQL的全同步模式)。
可見傳統(tǒng)主備方式下,如果要求數(shù)據(jù)不丟,那么基本放棄了服務(wù)的持續(xù)可用能力。
Paxos算法是Leslie Lamport在1990年提出的一種基于消息傳遞的一致性算法。由于算法難以理解,起初并沒有引起大家的重視,Lamport在1998年將論文重新發(fā)表到TOCS上,即便如此Paxos算法還是沒有得到重視,2001年Lamport用可讀性比較強的敘述性語言給出算法描述。
06年Google發(fā)布了三篇論文,其中在Chubby鎖服務(wù)使用Paxos作為Chubby Cell中的一致性算法,Paxos的人氣從此一路狂飆。
基于Paxos協(xié)議的數(shù)據(jù)同步與傳統(tǒng)主備方式最大的區(qū)別在于:Paxos只需超過半數(shù)的副本在線且相互通信正常,就可以保證服務(wù)的持續(xù)可用,且數(shù)據(jù)不丟失。
Basic-Paxos解決的問題:在一個分布式系統(tǒng)中,如何就一個提案達(dá)成一致。
需要借助兩階段提交實現(xiàn):
Prepare階段:
Proposer選擇一個提案編號n并將prepare請求發(fā)送給 Acceptor。
Acceptor收到prepare消息后,如果提案的編號大于它已經(jīng)回復(fù)的所有prepare消息,則Acceptor將自己上次接受的提案回復(fù)給Proposer,并承諾不再回復(fù)小于n的提案。
Accept階段:
當(dāng)一個Proposer收到了多數(shù)Acceptor對prepare的回復(fù)后,就進(jìn)入批準(zhǔn)階段。它要向回復(fù)prepare請求的Acceptor發(fā)送accept請求,包括編號n和根據(jù)prepare階段決定的value(如果根據(jù)prepare沒有已經(jīng)接受的value,那么它可以自由決定value)。
在不違背自己向其他Proposer的承諾的前提下,Acceptor收到accept請求后即接受這個請求。
參考資料
《The Part-Time Parliament》,Leslie Lamport,May 1998,論文原文
《Paxos Made Simple》,Leslie Lamport,Nov 2001
《一步一步理解Paxos算法》,相對通俗易懂
《使用Basic-Paxos協(xié)議的日志同步與恢復(fù)》,偏實現(xiàn)
Mulit-Paxos解決的問題:在一個分布式系統(tǒng)中,如何就一批提案達(dá)成一致。
當(dāng)存在一批提案時,用Basic-Paxos一個一個決議當(dāng)然也可以,但是每個提案都經(jīng)歷兩階段提交,顯然效率不高。Basic-Paxos協(xié)議的執(zhí)行流程針對每個提案(每條redo log)都至少存在三次網(wǎng)絡(luò)交互:1. 產(chǎn)生log ID;2. prepare階段;3. accept階段。
所以,Mulit-Paxos基于Basic-Paxos做了優(yōu)化,在Paxos集群中利用Paxos協(xié)議選舉出唯一的leader,在leader有效期內(nèi)所有的議案都只能由leader發(fā)起。
這里強化了協(xié)議的假設(shè):即leader有效期內(nèi)不會有其他server提出的議案。因此,對于后續(xù)的提案,我們可以簡化掉產(chǎn)生log ID階段和Prepare階段,而是由唯一的leader產(chǎn)生log ID,然后直接執(zhí)行Accept,得到多數(shù)派確認(rèn)即表示提案達(dá)成一致(每條redo log可對應(yīng)一個提案)。
相關(guān)產(chǎn)品
X-DB、OceanBase、Spanner都是使用Multi-Paxos來保障數(shù)據(jù)一致性。
MySQL Group Replication的xcom中也使用了Multi-Paxos。
參考資料
《使用Multi-Paxos協(xié)議的日志同步與恢復(fù)》
?
X-PaxosX-Paxos是X-DB中的Multi-Paxos實現(xiàn),通過異步流水線化、Batching和Pipeline等手段提升性能。
參考資料
《阿里如何實現(xiàn)高性能分布式強一致的獨立 Paxos?基礎(chǔ)庫》
PaxosStore是我司W(wǎng)XG基于Paxos實現(xiàn)的分布式一致性中間件,在微信的用戶賬號管理、用戶關(guān)系管理、即使消息、社交網(wǎng)絡(luò)、在線支付等場景中廣泛應(yīng)用。
參考資料
《PaxosStore:High-availability Storage Made Practical in WeChat》,PaxosStore在VLDB發(fā)的論文
PaxosStore(C++)
https://github.com/tencent/paxosstore
PaxosStore是騰訊公司W(wǎng)XG基于Paxos實現(xiàn)的分布式一致性中間件。
PhxPaxos(C++)
https://github.com/Tencent/phxPaxos
PhxPaxos是騰訊公司微信后臺團(tuán)隊自主研發(fā)的一套基于Paxos協(xié)議的多機狀態(tài)拷貝類庫。它以庫函數(shù)的方式嵌入到開發(fā)者的代碼當(dāng)中, 使得一些單機狀態(tài)服務(wù)可以擴展到多機器,從而獲得強一致性的多副本以及自動容災(zāi)的特性。這個類庫在微信服務(wù)里面經(jīng)過一系列的工程驗證,并且其開發(fā)團(tuán)隊對它進(jìn)行過大量的惡劣環(huán)境下的測試,使其在一致性的保證上更為健壯。
LibPaxos(C)
http://libPaxos.sourceforge.net/
LibPaxos的主要價值是可以用來做研究,可以讓程序員對Paxos的細(xì)節(jié)了解更加清楚。
如果要基于LibPaxos實現(xiàn)一個可以用于生產(chǎn)環(huán)境的Paxos庫,還需要做幾個工作:
各個單元的狀態(tài)信息固化,防止宕機發(fā)生信息丟失;
增加leader模型;
改為多線程實現(xiàn)并合并learner、proposer、acceptor為一個進(jìn)程;
對庫做充分細(xì)致的測試。?
Raft是斯坦福大學(xué)的Diego Ongaro、John Ousterhout兩個人以易理解為目標(biāo)設(shè)計的一致性算法,在2013年發(fā)布了論文:《In Search of an Understandable Consensus Algorithm》。從2013年發(fā)布到現(xiàn)在,已經(jīng)有了十幾種語言的Raft算法實現(xiàn)框架,較為出名的有etcd,Google的Kubernetes也是用了etcd作為他的服務(wù)發(fā)現(xiàn)框架。
與Paxos相比,Raft強調(diào)的是易理解、易實現(xiàn),Raft和Paxos一樣只要保證超過半數(shù)的節(jié)點正常就能夠提供服務(wù)。
眾所周知,當(dāng)問題較為復(fù)雜時,可以把問題分解為幾個小問題來處理,Raft也使用了分而治之的思想,把算法分為三個子問題:
選舉(Leader election)
日志復(fù)制(Log replication)
安全性(Safety)
?分解后,整個raft算法變得易理解、易論證、易實現(xiàn)。
相關(guān)產(chǎn)品
etcd使用Raft來保障數(shù)據(jù)一致性。
參考資料
《In Search of an Understandable Consensus Algorithm》,Diego Ongaro,John Ousterhout,2013
《一致性算法Raft詳解》
許多NewSQL數(shù)據(jù)庫的數(shù)據(jù)規(guī)模上限都定位在100TB以上,為了負(fù)載均衡,都會對數(shù)據(jù)進(jìn)行分片(sharding),所以就需要使用多個Raft集群(即Multi-Raft),每個Raft集群對應(yīng)一個分片。
在多個Raft集群間可增加協(xié)同來減少資源開銷、提升性能(如:共享通信鏈接、合并消息等)。
相關(guān)產(chǎn)品
TiDB、CockroachDB、PolarDB都是使用Mulit-Raft來保障數(shù)據(jù)一致性。
Parallel-Raft是PolarDB中的Multi-Raft實現(xiàn),通過支持亂序日志復(fù)制(亂序確認(rèn)、亂序提交、亂序應(yīng)用)等手段來提升性能。
參考資料
《面向云數(shù)據(jù)庫,超低延遲文件系統(tǒng)PolarFS誕生了》
《PolarFS: An Ultra-low Latency and Failure Resilient Distributed File System for Shared Storage Cloud Database》,PolarDB在VLDB上發(fā)的論文
etcd/raft(Go)
??etcd里面使用raft做數(shù)據(jù)同步
https://github.com/etcd-io/etcd
應(yīng)用廣泛,成熟度高。因為是Go語言開發(fā),集成到C/C++應(yīng)用中比較困難。
TiKV/raft(Rust)
TiKV里面使用raft做數(shù)據(jù)同步
https://github.com/tikv/tikv
Rust語言目前還比較小眾。
kudu/raft(C++)
kudu里面也使用了raft
https://github.com/apache/kudu
LogCabin(C++)
https://github.com/logcabin/logcabin
由Raft論文作者Diego Ongaro主導(dǎo)的開源項目,沒有得到廣泛應(yīng)用,很久沒更新了。
其他實現(xiàn)
目前有十幾種語言實現(xiàn)的幾十個Raft算法實現(xiàn)框架,參見:
https://raft.github.io?
Raft是基于對Multi-Paxos的兩個限制形成的:
發(fā)送的請求的是連續(xù)的, 也就是說Raft的append 操作必須是連續(xù)的, 而Paxos可以并發(fā) (這里并發(fā)只是append log的并發(fā), 應(yīng)用到狀態(tài)機還是有序的)。
Raft選主有限制,必須包含最新、最全日志的節(jié)點才能被選為leader. 而Multi-Paxos沒有這個限制,日志不完備的節(jié)點也能成為leader。
Raft可以看成是簡化版的Multi-Paxos。
Multi-Paxos允許并發(fā)的寫log,當(dāng)leader節(jié)點故障后,剩余節(jié)點有可能都有日志空洞。所以選出新leader后, 需要將新leader里沒有的log補全,在依次應(yīng)用到狀態(tài)機里。
參考資料
知乎里朱一聰做的比較相對客觀、全面:
https://www.zhihu.com/question/36648084/answer/82332860
總結(jié)
以上是生活随笔為你收集整理的Paxos和Raft的前世今生的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大牛书单 | 数据库专题好书分享
- 下一篇: Fashion-MNIST 一周年 |