Raft一致性算法

每个结点都只能是以下3种状态中的一种:
1、领导者
2、候选者
3、跟随者

状态转换:
这里写图片描述
跟随者只能回应其它服务器的请求。如果一个跟随者收不到信息,则变为候选者,发起选举。一个候选者如果获得大多数选票,则成为新的领导者,直到它失效。

Raft确保任何时期,都满足:
1、选举安全:给定时期内至多有一个领导者。
2、领导者从不重写或删除它的日志,它只增加新的日志。
3、日志匹配:如果两个日志包含同时包含这样的条目:下标、时期都相同,那么在给定索引情况下,条目相同。
4、领导者完备性:如果一个一条日志条目在某个时期已提交,它会出现在所有比它时期号更大的领导者中。
5、状态机的安全性:如果一个服务器将给定下标的日志条目提交,其它的服务器不会提交一条具有相同下标,但不一致的日志条目。

领导者选举
选举超时:从跟随者变为候选者的时间。

领导者使用“心跳机制”来维持自己的地位,如果一个跟随者在“选举超时”后仍未收到“心跳”, 则认为领导者已经失效,发起选举。它将增大自己的“当前时期”,转为候选者。它会给自己投一票,然后请求其它服务器的投票,将会有以下3种情况发生:
1、它在同一时期内获得了大多数选票,赢得了选举。然后给其它服务器发送“心跳”信息,其它服务器会比较自己的“时期”与新领导者的“时期”,如果新领导者的“时期”大或相等,则转为跟随者;否则,不承认该领导者,继续保持候选者状态。
2、别的服务器赢得了选举。
3、任何服务器都没有赢得选举。如果大多数服务器同时成为候选者,则谁也没有办法赢得大多数选票,新一轮的选举即将开始。为了避免这种情况,每个服务器的“选举超时”随机从150~300ms取值。

投票规则:
一个服务器只能投给一个候选者,哪个候选者先发出请求,就投给谁。

结果:
一个时期内至多有一个领导者。

这里写图片描述
时间被划分为了时期,每个时期都始于选举。一次成功的选举后,比如term1,term2,term4,一个领导者会管理集群,直到该时期结束。有时选举会失败,比如term3,这种情况下,该时期会以无领导者结束。

日志复制
领导者者被选出来后,就会接受客户端请求。将客户端的命令添加到它的日志中,然后复制给跟随者,跟随者写到日志中。当领导者收到大多数跟随者们写日志成功的消息后,便应用到状态机,即提交该日志条目,然后给客户端返回结果。当某个跟随者慢了,或者失效,或者丢失信息,领导者就无限次发送,直到它包所有日志条目写成功。
这里写图片描述
每个小方格在代表一个日志条目,小方格子中的数字代表“时期号”,即该日志是哪个时期产生的。日志条目存的时候,是同“命令”、“时期号”、“下标”一起存的,便于日后进行一致性检查。

日志匹配满足:
1、如果两个不同的日志中的某个条目具有相同的下标和时期,那么这两个条目内容相同。
2、如果两个不同日志的某个条目具有相同的下标和时期,那么在该条目之前的日志内容相同。

第一条是因为领导者在给定时期和下标的情况下,只会产生一条日志条目,之后日志条目的位置都不会改变。第二条通过简单的一致性检查来保证,领导者发送“心跳”时,会连同日志条目、下标、时期一起发送,跟随者如果找不到具有相同下标和时期的日志条目,则拒绝接受(我的理解是,这说明自己比领导者更大,时期更新,所以不承认该领导者)。

有时候,领导者会宕机
这里写图片描述
最上面是时期8的领导者。一些跟随者者丢失一些日志条目(a~b),一些跟随者多出一些未提交的日志条目(c~d),或者是两种情况兼具(e~f)。对于f,它是时期2的领导者,但日志未提交就宕机了,就产生了这种情况;如果它很快恢复,又成为时期3的领导者,又添加了一些日志,然后又宕机了,于是就多出了未提交的日志(时期2的、时期3的)。

为了保持一致性,领导者必须从后向前找出两个日志相同的地方,然后在随者中删掉那个点之后的日志,再将自己的日志复制过去。

安全

1、领导选举限制

当一个领导者a提交日志时,跟随者b可能宕机了,当该跟随者当选为领导者后,就会重新a中与之不一致的日志,这样的话就不能保持一致性了。

Raft的投票选举过程便可以保证,一个候选者只有提交了所有日志,才能被选为领导者:一个服务器会投票给候选者,当且仅当自己的日志比候选者更“新”。

更“新”:如果两个日志的最近日志条目时期不同,那么时期大的更“新”;如果两个日志的最近日志条目时期相同,那么日志更长的更“新”。

2、提交前一个时期的日志条目

这里写图片描述
在(a)中,S1是领导者,并且将自己下标为2的日志复制到了S2;在时期3中,S5收到了S3、S4的投票,成为了领导者,在下标2处接收了不同的日志条目。在(c)中,S5宕机了;S1重新被选为领导者,继续将下标为2的日志条目复制给S3,这时,时期2的日志被复制给了大多数服务器,但还没有提交。如果S1在(d)宕机了,S5可能重新成为领导者,并用时期3的日志重写S1~S3时期2的日志。但是,如果S1在宕机之前,将时期4的日志复制给大多数服务器,那么即使它宕机了,S5也不肯能当选为领导者,如(e),然后日志被提交。

即使一个日志条目被复制给了大多数服务器,如果没有提交,还是有可能被新的领导者重写。

如何判断一个日志条目是否提交?
并不是该日志条目的副本多就算提交了,而是当前领导者的日志条目的副本多才算提交了。一旦当前日志条目提交了,就认为之前的也提交了。

集群关系更新

有时候需要更新集群配置,比如加入一些服务器。
C(new) 代表拥有新配置的集群
C(old)代表拥有旧配置的集群
C(old, new)代表前两者
当领导者收到将配置从C(old)更新到C(new)的消息时,就将这些消息存储在C(old, new)中,并作为一个日志条目,复制给其它服务器,一旦一个服务器添加了新的配置日志条目,以后也将沿用。领导者完备性保证了只有C(old, new)候选者才会被选为领导者。C(old, new)提交后,C(new)日志条目就可以复制给其它服务器,C(new)被提交后,旧的配置就可以完全下线了。

这里写图片描述

虚线表示配置日志条目已经产生但还没有提交,实线表示最近的被提交的日志条目。领导者产生配置日志条目C(old, new),然后提交。然后产生C(new),然后提交。

参考
In Search of an Understandable Consensus Algorithm. Diego Ongaro and John Ousterhout, Stanford University

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值