Raft原理

参考

  1. 英文原版
  2. 中文版本

三种身份

节点初始身份都是follower状态

  1. follower 跟随者(初使状态)
  2. candidate 候选者
  3. leader 领导者

两个定时器

  1. 选举定时器
  2. 心跳定时器

选举过程

  1. 初始为follower状态,当没有收到心跳通知,则自身的超时,则切换成candidate状态
  2. 变成candidate状态后,向其它节点发起投票.
  3. 接收到的节点会回复这次投票.
  4. 如果本次投票得到多数赞同,则从candidate状态成为leader状态,其它的candidate切换为follower
  5. 然后向其它节点向起心跳维护leader与follower的关系.
  6. 标记本次选举届, 如第1届,每发起一次加1
  7. 之后所有的操作变化指令都由leader来决定

选举详细过程

  1. 由两个超时时钟决定着选举过程
  2. 首先是竞选超时
  3. 竞选超时是指跟随者成为候选人的时间
  4. 竞选超时一般是150毫秒到300毫秒之间的随机数
  5. 当到达竞选超时时间后,跟随者转变为候选人角色,并进入到 选举周期...
  6. 先为自己投一票.
  7. 此时候选人将发送 投票请求 给其它节点
  8. 如果收到请求的节点在当前选举周期中还没有投过票,则这个节点会投票给这个候选人...
  9. 然后这个节点重置它的选举周期时间,重新计时
  10. 一旦候选人获得半数以上的赞成投票,那么它将成为领导人
  11. 之后领导人将发送 附加日志 指令给跟随者
  12. 这些消息是周期性发送,也叫 心跳包(以此来保证它的领导人地位)
  13. 跟随者将响应 附加日志 消息
  14. 选举周期将一直持续直到某个跟随者没有收到心跳包并成为候选人

当leader挂了会如何, 将发起第二轮选举.

A, B, C节点, 第1届A为leader, 当A挂掉后

  1. 重新选举之后,节点 B 是选举周期2 时的领导人了
  2. 多数票赞成能保证每届只有一个领导人可以当选
  3. 如果同一时间有两个候选人,则会出现投票分裂的情况

得不到更多投票产生的脑裂过程

  1. 在同一个周期里有两个节点同时发起了竞选请求...
  2. 并且每个都收到了一个跟随者的投票响应
  3. 现在,每个候选人都有两票,并且都无法获得更多选票
  4. 这种情况下,两个节点将等待一轮竞选超时后重新发起竞选请求
  5. 节点A 在 竞选超时5 里得到了大多数选票,所以它成为了新领导人

日志复制(2pc)

  1. client向leader发起一个:set 5操作
  2. leader会先保存在日志,并没有提交.
  3. leader在提交日志之前, 会将指令同步到跟随者的节点日志中
  4. leader进入等待状态, 直到收到大多数节点记录成功的响应.
  5. 此时leader将提交日志, 然后leader通知所有follower提交日志.
  6. 最终集群达成一致.

日志复制详细过程

  1. 一旦选举出了领导者,我们需要向所有节点通知这一消息,并需要持续维持领导人地位
  2. 这是通过周期性的发送 附加日志 消息(心跳包)实现的
  3. 首先,一个客户端发送变化的数据给领导人
  4. 这条变更记录被添加到领导人的日志里...
  5. 然后在下一个心跳中将变更记录发送给跟随者
  6. 一旦大多数的跟随者确认了这条记录,那么这条记录就会被提交...
  7. 最后将响应客户端

网络分区导致脑裂

  1. 假如我们增加了一个分区,并将A和B分为一组,C、D和E分为一组
  2. 由于分区原因,系统中出现了两个不同的领导人
  3. 现在新加一个客户端并且试着修改两个领导人的数据
  4. 其中一个客户端将把节点B的值设置为"3"
  5. 但节点B不能同步大多数,所以他的日志记录仍为未提交
  6. 另一个客户端将修改 节点C 的值为"8"
  7. 因为可以同步大多数,所以这个操作能够成功
  8. 随后,我们修复了网络分区问题
  9. 节点B将会发现存在"更高领导人",所以将会选择"下台"(每产生一次选举, 有一个标记记录加1)
  10. 此时,节点A和节点B将会回滚它们未提交的记录,并同步新领导人的日志
  11. 最终,我们集群达成了一致
网络分区导致脑裂

最终,我们集群达成了一致

你可能感兴趣的:(Raft原理)