RAFT算法随想

    之前在部门内做了一个关于RAFT算法的分享,在制作PPT的过程中把RAFT算法重新温习了一遍,把RAFT内在逻辑与论文中没有说明的一些问题做了整理。把这些内容整理成文字如下。


一、确定性状态机

    RAFT论文与Paxos论文中都有提及。如Paxos make simple中提到的:服务器可以看成是一个以某种顺序执行客户端命令的确定性状态机。

    为什么是确定性状态机呢?其实这和主备同步有关。

    确定性状态机的意思是:对于一个输入,只有一个固定的状态变迁。而非确定状态机则是有多种状态变迁,选择其中一种。在主备同步过程中,若同步的命令不满足确定性的要求那么主备就无法保持一致。例如:

要同步一个命令 x=rand(),在主上执行的结果很可能与备是不同的,因此此时在同步命令时就需要对该命令进行转换。如:在Master上执行的结果为 x=100; 那么Master可以将x=100这条命令同步给Slave就能够实现状态一致。

也就是说,Master在执行命令时,若一条命令不满足确定性的条件,那么Master要根据执行结果将其转换成确定性的命令同步给Slave以保持主备一致。


二、丢弃term<current term的请求

    看论文的时候当请求报文的term参数小于current term时,只是笼统的说返回false或者拒绝。这点参考了etcd的源码,在etcd之中的处理是直接丢弃该请求报文。etcd之中,对于每个请求报文会做两个检查,首先请求者ID必须是认可的集群成员,其次是term要大于等于current term,若不满足任何一个都是丢弃请求报文。丢弃应该是比返回false更好的方法,比如:一个已经被删除的成员向集群中发消息,此时通过检查请求者ID是否属于集群成员的方式就可以避免受到干扰。返回false就会把current term带上,对方受到该回复报文之后,由于自己的term较小就会立即转换成Follower,那么原先的集群马上就没有Leader


三、Leader自动降级

    Leader根据心跳超时时间向外发送心跳包,以获取Follower的授权。假若在一个选举超时时间内没有收到多数Follower的授权回复,此时Leader可以采取降级措施,以避免存在两个Master的请情况。

    在ETCD之中,这种自动降级操作是可配置的,默认不会自动降级。若没有自动降级,在收到新Leader心跳包时,由于请求的term>current term,则老Leader自动变成Follower

但是若该Leader处于一个网络分区之中,可能收不到新Leader的心跳包,因此配置成自动降级是比较合理的。


四、日志的顺序复制与preLogTermpreLogIndex匹配规则

    RAFT算法中的日志必须是顺序复制的。就是说,假如有一条旧的日志还未复制给FollowerA,那么更新的日志就不能复制。因为,如果Follower接收了该日志,那么就会造成日志空洞。其次,根据复制日志时必须匹配preLogIndexpreLogTerm的要求,实际上也无法满足该条件,因此当有旧日志未复制,而直接复制新日志,Follower应该返回false

    日志的顺序复制,很大程度上简化了Raft算法。比如查看各成员日志的新旧,只要比较最后一条日志即可。

    preLogTermpreLogIndex的匹配规则是用于实现顺序复制的手段。有了这个规则,根据归纳假设就很容易得到所有的Follower日志最终都会与Leader完全一致。


四、新的Leader为何必须具有所有已提交日志

    根据Raft的日志复制规则,所有的Follower的日志最终会与Leader的日志完全一致。另外若一个日志被设置成已提交,那么必须假设该条日志被应用于状态机。

    因此若一条日志被一个Leader提交了,即使该Leader提交日志,应用到状态机之后,提交状态还未同步给Follower就宕机了,也要保证所有其他机器在将来将该日志应用到状态机。又因为Follower的日志提交与日志内容都是完全与Leader一致,那么就需要保证后续的Leader必须具有原Leader提交的日志,并且会在何时的时候提交,然后将提交状态同步给Follower,然后Follower提交并应用到状态机。


五、新的Leader如何保证具有前面Leader提交的日志

    这是通过Leader选举规则来保证的。前面说过,日志是顺序复制的,日志的新旧可以通过查看最后一条日志来判断。

    在Leader选举中,请求报文中有Candidate最后一条日志的termindex。收到投票请求的Follower会检查本地最后一条日志的termindex。只有Candidate的最后一条日志大于等于本地日志时才能投票。

    而提交日志的条件是日志复制给集群中的多数成员,Candidate选举为Leader的条件也是需要多数成员的投票。那么这两个成员之间必须有一个交叉,即有一个成员具有该日志,并且投票给了新Leader,也就意味着新Leader的日志至少不比该成员旧,那么新Leader也具有该日志。这样就得到证明了,后续的Leader一定具有前面Leader提交的日志。


六、为何一个Leader不能提交前面Term下的日志

    假设新的term=10,要提交term=8的日志。那么在term=9的时候有一个Leader,这个Leader是在提交term=8这条日志之前就选出来的。因此term=9的这个Leader不能保证会有term=8的这条日志。若term=10的这个Leader提交term=8的日志并应用到状态机之后,马上宕机。而term=9的这个Leader重新选举为term=11Leader,那么term=8的这条日志很可能就被新Leader覆盖掉,而再不会被提交与应用。

    其实这里的关键就是:新的Leader会有前面Leader提交的日志,而旧的Leader则不能保证。


七、过度配置保证不会在oldnew两个配置上同时产生Leader的证明

    过度配置是指集群具有 old + new 中所有机器的配置。

    Leader会产生一个过度配置日志,先应用到本地,然后复制给过度配置中的所有成员。所有收到配置的成员,会直接将配置应用到本地。

    处于过度配置的成员,在Leader选举与提交日志时规则发生了变化,都要求分别得到OldNew两个配置下的多数成员同意才行。比如:

    Old123

    New2345(删除机器1,增加机器456

    Old+New123456(机器是Old+New所有机器)

    那么处于过度配置的成员在Leader选举与提交日志,需要满足得到 Old123)三个成员中的多数,以及New23456)五个成员中的多数。而不是Old+New中六个成员的多数。明白这点非常关键。

    1)从Old -> Old+New配置提交之前

    此时还未产生New配置,因此不可能在New配置下产生Leader

    看下是否可能在OldOld+New下分别产生LeaderOld下要产生Leader需要Old中的多数投票,Old+New下要产生Leader也需要Old中的多数投票,而要在OldOld+New下分别产生Leader,那么在Old中至少有一个成员同时投票给Old中的Leader,与Old+New中的Leader。根据投票规则,在一个term下只能投票一次,因此就不可能在OldOld+New配置下在同一个term上产生Leader

    而在不同term下产生则不违反规则,因为新的term下产生的Leader,发送心跳给旧Leader,旧Leader就会马上变成Follower

    2Old+New提交之后

    只要Old+New这个配置提交,则意味着该配置以及复制给了Old中的多数成员,那么在Old配置中就不可能再产生一个Leader出来了。只能在Old+NewNew配置下产生。而在Old+NewNew中也不可能在同一个term下分别选举出Leader,这个证明与OldOld+New配置是一样的。


八、若每次增加或者删除一个成员不需要过度配置

    就是说,每次配置变更只能增加或者删除一个成员。若满足则可以直接从Old配置转换到New配置。

    证明旧配置有N个成员,新配置有N+1个成员,在切换过程中不会再旧配置与新配置下分别产生Leader

    1)若旧配置下选举出Leader,那么需要N/2+1个成员投票。

    2)新配置下,从成员数是N+1去掉以及投票的N/2+1个成员只剩下N/2个成员。

    3)而新配置下要选举出Leader需要(N+1)/2+1=N/2+3/2个成员投票,但是只剩下N/2个成员可以投票,因此新配置下不可能再选举出Leader

    4)反过来也一样。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值