深度比较Paxos和Raft
比较Paxos和Raft
- 前言
- leader选举
- 日志同步
- Commit Index推进
- 崩溃恢复
- 成员变更
前言
我一直在讲学习paxos和raft最好的方式就是看作者的论文和视频,只有看原滋原味的文章,才能真正体会到作者的设计思路,才能在现代繁杂的工程实践中抓住精髓。
这篇文章作为系列文章的最后一篇,我想谈谈paxos与raft的异同。算法在变,但是其中的核心思想是不变的。
- 一致性协议raft详解(一):raft整体介绍
- 一致性协议raft详解(二):安全性
- 一致性协议raft详解(三):raft中的消息类型
- 一致性协议raft详解(四):raft在工程实践中的优化
- 一致性协议Paxos详解(一):Basic Paxos协议详解
- 一致性协议Paxos详解(二):Multi-Paxos协议流程详解
- 一致性协议Paxos详解(三):Multi-Paxos的优化
paxos共识协议是后面所有一致性协议的基础,据说Google Chubby的作者Mike Burrows说过:这个世界上只有一种一致性算法,那就是Paxos,其它的算法都是残次品。raft协议在paxos协议的基础上,抽象出了一个共识协议需要做的以下几个事情:
- Leader选举(Leader Election)
- 日志同步(Log Replication)
- Commit Index推进(Advance Commit Index)
- 崩溃恢复(Crash Recovery)
- 成员变更(Membership Change)
当然每个共识协议不需要都实现这里面每个方面,但其设计思路上一定是考虑过这些问题,然后根据实际需求做出取舍的。下面我们一个个来说,顺便比较paxos/raft的异同。我们这里讲的paxos主要是multi-paxos with leader这种工程上比较常见的版本。basic paxos这种只对单个决议作出共识的算法和raft可比性不大。
leader选举
既然Multi-Paxos支持多个proposer,为什么很多分布式协议仍需要leader?我觉得这是出于对简化一致性协议。降低log replication的复杂度的角度考虑的。有了leader之后,日志的提交只可以由leader发起。简化了acceptor的处理流程。另外一个好处是,单leader对事务比较友好。各种隔离级别实现起来也比较方便。
当然,引入leader必然要在一致性协议中引入leader选举过程,一个集群怎样保证只有一个leader?切主的时候集群的可用性如何?一致性如何保证?都是设计者需要考虑的问题。
- multi-paxos理论上任何成员都可以成为leader,但是leader当选时要补齐自己本地缺失的日志,还要将自己已经chosen的日志在集群内进行广播,这个过程可以叫做日志的“重确认”
- raft由于增加了对日志的顺序性保证,并且leader只允许commit当前term的日志,因此raft集群的leader选举遵循最大提交原则: During elections, choose candidate with log most likely to contain all committed entries。只有包含最全日志的节点才可能被选为leader。
日志同步
log replication是一致性协议的核心。paxos和raft最大的区别也在这里
- multi-paxos允许日志乱序提交,也就是说允许日志中存在空洞。
- raft协议增加了日志顺序性的保证,每个节点只能顺序的commit日志。顺序性日志简化了一致性协议复杂程度,当然在性能上也有了更多的限制,为此,工程上又有了很多对应的优化,如:batch、pipline、leader stickness等等。有关pipline的优化可以看这篇文章
- 另外再多说一句,乱序不乱序的问题其实还是上层业务决定、体现到RSM中的。如果两条日志有关联性,就算用paxos协议,业务还是要想办法保证这种顺序。如果使用raft希望乱序提交,大可使用多个raft组。
还有一个隐含的区别:raft/paxos如何对待读请求?处理读请求的关键是,leader怎样才能知道某条log已经在整个集群内达成共识了(paxos叫chosen,raft叫commit)
- multi-paxos的leader维护了每一条LogEntry是否被chosen的信息。但是对未chosen的LogEntry,leader必须重新走paxos流程,才能知道它是否已经被chosen了(“薛定谔的提案”),当然,leader可以在当选时对这些LogEntry执行propose,迅速掌握这些日志的状态。
- raft协议有顺序性保证,leader通过在后续提交的过程中对其他节点间接提交,可以将集群的状态迅速补齐。但是leader刚当选的时候,它是不清楚自己的日志是否真的commit了。这时我们可以通过引入no-op,让新当选的leader迅速获取系统的CommitIndex,方便提供读服务。
当日志过多之后,需要对已经确认提交的日志做快照(snapshot),将日志压缩、持久化。后续新上线的节点也可以通过读取快照的方式迅速追齐日志。
Commit Index推进
一条写请求到达paxos/raft集群之后,到底存放在哪里,这是CommitIndex想要解决的问题
- raft得益于其顺序日志的设计,CommitIndex的推进比较简洁。leader不会持久化CommitIndex,而是在当选后与follower交互的过程中获取。leader只能推进commit index来提交当前term的已经复制到大多数服务器上的日志,旧term日志的提交要等到提交当前term的日志来间接提交
- Multi-Paxos由于可以乱序提交,index的推进稍显麻烦。leader在收到client的写日志请求后,首先要找到空闲的可以提交日志的entry。最简单的方法是可以LogIndex从低到高尝试应用paxos去propose,找到一个没有任何value的LogEntry,去放置新的LogEntry。
崩溃恢复
- raft比较巧妙的一点是,通过对日志的顺序性保证,将crash recovery做到了log replication里面。也就是之前提到的:leader只能推进commit index来提交当前term的已经复制到大多数服务器上的日志,旧term日志的提交要等到提交当前term的日志来间接提交。leader在这个过程中会覆盖于follower不一致的LogEntry。
- Multi-Paxos的崩溃恢复要复杂的多:
- 新当选的leader要完整的对所有日志走一遍prepare流程。从而:
- Block old proposals:这里我们需要将ProposalId的影响范围扩展到整个log上,而不只是某个LogEntry。通过这样做,只要当前leader发送了proposal,自然就可排除掉之前的proposal
- Find out about (possibly) chosen values:不同的acceptor上可能会有不同的
acceptedProposal
,所以,acceptor需要回复[highestProposalIdForCurrentEntry, noMoreAccepted]
,通过这种方式,辨别每一个acceptor到底有哪些LogEntry,以及其状态是什么。通过这种方式,leader可以将已经chosen的LogEntry在整个集群中对齐
- 对于之前term的日志,leader对自己已经chosen但是其他节点未chosen的LogEntry,对该节点发送
Success RPC
。leader通过这种方式告诉acceptor,某个LogEntry已经被Chosen了。 - 注意,通过success这种方式,只能将chosen的LogEntry在整个集群中对齐,推动整个集群的Log index。但是对于未被chosen的之前的LogEntry,处理的不好会导致所谓的幽灵复现的问题,最简单地解决方式:Leader直接把之前未提交LogEntry全部提交,这也是raft使用的方法。
- 新当选的leader要完整的对所有日志走一遍prepare流程。从而:
成员变更
成员变更的论证在这里不再详述,raft和paxos以及所有的工程实现都明白:成员变更需要特殊对待,以防在变更过程中集群同时出现两个多数派。
很多的工程实现将成员变更作为一条日志,apply进集群节点的RSM。并且为了简单,很多工程每次只允许一个节点变更,上一次变更成功之后才允许下一个变更。
深度比较Paxos和Raft相关推荐
- 从paxos到raft zab,为何raft能够“独领风骚”
文章目录 RAFT出现的缘由 RAFT 的实现 STATE MACHINE Log Replicated State Machine Leader Election 基本角色 关键变量 基本选举过程 ...
- 超详细解析 | 一致性协议算法-2PC、3PC、Paxos、Raft、ZAB、NWR
点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源:r6d.cn/VMW9 背景 在常见的分布式系统中, ...
- Paxos、Raft不是一致性算法/协议?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作为互联网中的一员,我们时常沉浸在"分布式"的 ...
- 一致性协议算法-2PC、3PC、Paxos、Raft、ZAB、NWR超详细解析
背景 在常见的分布式系统中,总会发生诸如机器宕机或网络异常(包括消息的延迟.丢失.重复.乱序,还有网络分区)等情况. 一致性算法需要解决的问题就是如何在一个可能发生上述异常的分布式系统中,快速且正确地 ...
- 区块链共识算法 PBFT(拜占庭容错)、PAXOS、RAFT简述
共识算法 区块链中最重要的便是共识算法,比特币使用的是POS(Proof of Work,工作量证明),以太币使用的是POS(Proof of Stake,股权证明)使得算理便的不怎么重要了,而今PO ...
- Paxos、Raft分布式一致性算法应用场景
本文是Paxos.Raft分布式一致性最佳实践的第一篇文章,说明分布式一致性问题与分布式一致性算法的典型应用场景,帮助后面大家更好的理解Paxos.Raft等分布式一致性算法. 一.分布式一致性 (C ...
- 分布式系统概念 | 一致性协议:拜占庭将军问题、Paxos、Raft
文章目录 拜占庭将军问题 Paxos 问题描述 执行过程 Prepare阶段 Accept阶段 Learner获取提案 活锁问题 Raft 状态机 执行流程 主节点选举 数据同步 拜占庭将军问题 拜占 ...
- 2PC到3PC到Paxos到Raft到ISR
序 本文主要讲述2PC及3PC,以及Paxos以及Raft协议. 两类一致性(操作原子性与副本一致性) 2PC协议用于保证属于多个数据分片上的操作的原子性.这些数据分片可能分布在不同的服务器上,2PC ...
- 分布式一致性算法——Paxos 和 Raft 算法
写在前面 本文隶属于专栏<100个问题搞定大数据理论体系>,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见100个问题搞定大数据理 ...
最新文章
- mysql safe 关闭_新手请教,mysqld经常自动关闭是什么原因?-问答-阿里云开发者社区-阿里云...
- Mysql 中文乱码问题完美解决方案
- Ubuntu 12.04 下编译Android 4.0.3
- CASE WHEN 高阶用法?
- Python中爬虫框架或模块的区别!
- Go的sync.Pool(五)
- (转)使用DataGridView控件常见问题解答
- php怎么解析xml,使用PHP快速解析复杂的XML文件
- go odroid_小众奇葩!Odroid Go Super简评
- mysql数据没有同步更新_MySQL数据库主从没有同步的两种解决方案
- 极致物业管理软件的系统特点
- 【考研高数 自用】高数第一章基础阶段思维导图
- 数据分析实战(三) 因子分析模型挖掘CSDN优质博主
- 如何使用腾讯云存储图片
- css3实现鼠标移入图片划过一束光闪过效果
- Element-UI组件实现全局回到顶部功能
- python小学生能学嘛_小学生都能学会的python(深浅拷贝)
- 解决Attribute 'transaction-manager' is not allowed to appear
- 四大Linux备份工具比较与操作实例
- WEB攻防-通用漏洞文件包含LFIRFI伪协议编码算法代码审计
热门文章
- 对于容斥原理反演的思考和总结
- gSOAP中内存的使用
- 长连接和Keepalive
- 再见,Navicat!这个IDEA的兄弟,真香!
- 50 种不同编程语言的“Hello World”,你知多少?
- 面试官:限制系统扩展能力的瓶颈有哪些?
- JQuery属性、事件相关操作
- LiveVideoStack线上分享第四季(八):实时远程医学影像服务质量保障与网络优化...
- PMP之项目资源管理---激励理论
- readlink(/proc/self/exe, buf, count - 1);