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