raft协议几点更正和补充

Posted bloomingTony

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了raft协议几点更正和补充相关的知识,希望对你有一定的参考价值。

上篇文章浅析了raft协议(),文章中有一处描述错误和理解不透彻的地方,在这里再补充下。

raft论文截图 1

第一、日志复制流程那一段提到的日志复制流程中的两阶段提交。是错误的,这里没有使用两阶段提交。客户端请求打到leader节点后,leader本地写日志,并将日志复制到集群其他follower节点,如果收到大多数(超过集群总数一半)的节点复制成功,并且满足安全性检查条件(存在当前选举term的日志复制),leader节点就认为可以提交,将log entry作用到本地状态机,并返回客户端写入成功的操作,至此客户端写入操作完成。不存在通知follower节点该log entry已提交的过程。

其实同步commitid是没有必要的,leader节点收到大多数节点返回的复制成功响应后就可以安全提交该log entry了,即使leader崩溃,该log entry在新的leader节点也是可见的。commitid在节点上是以volatile方式存储的,掉电或者重启后commitid会丢失,但是可以根据各节点已落盘的日志恢复出来。具体怎么恢复可以参考上述截图。


第二、安全性问题除了选举规则增加了选举最新的leader,还有一条是提交规则的修改。如果提交的日志记录是前一任期的,则必须跟随本届任期的日志记录一起提交才算安全提交。解释下:

raft论文截图2

(1)a时间段S1节点当选为term-2 leader,复制index-2日志到S2节点,崩溃了;


(2)b时间段S5当选为term-3  leader节点,选票来自S3 S4,并接收了一条来自客户端的请求,随即崩溃;


(3)c时间段S1节点恢复,当选为term-4 leader,选票来自S2 S3 S4,并将index-2 日志复制到S3节点,此时leader节点通过本地维护的matchIndex[]={2,2,2,1,1}数组发现index-2已经在大多数节点完成复制了,但是能将index-2的Log Entry提交到状态机吗?  不可以,原因:


(4)d时间段,如果此时S1崩溃,集群发起term-5的选举,S5轻而易举可以获胜,因为S5节点最新log Entry为(term-3,index-2),该日志比S2和S3的(term-2,index-2)日志新;此处日志是节点当前最新的日志,不是提交日志,日志比较优先比较term,term相等再比较index;


(5)S5当选为leader节点,会将(term-3,index-2)日志复制到其他节点,覆盖(term-2,index-2)


所以c时间段(term-2,index-2)log entry不能提交,什么时候能够提交呢?当(term-4,index-3)log entry提交时,(term-2,index-2)就可以安全提交,因为此时S5节点不可能再被选举为leader节点。


结论:当提交的log entry的term号为前一任期号时,必须跟随本届任期的log entry一起提交才算安全提交。


以上是关于raft协议几点更正和补充的主要内容,如果未能解决你的问题,请参考以下文章

Raft协议详解前言:子问题分解

Raft协议

raft 和 zab协议

聊聊分布式一致性协议---Raft协议

Raft协议简析

Raft协议处理各种failover情况