Raft系列6 AppendEntries RPC(原创)

可能是你能找到的最完整最详细的中文版的Raft算法说明博客

内容来源都是原生的论文,可以保证内容的可靠性,并且对论文里面的很多细节做了扩展说明

RPC组成和规则

image
  1. 参数
  • 当前leader的任期
  • learderId:follower本身也会存储当前leaderId,因为接收到写的请求的时候要转发给leader,所以这个参数是为了更新最新的leaderId的身份,避免follower存储的是老leaderId
  • prevLogIndex:添加下面log的前一个log的Index,非常关键的一个指标,理论上正常情况下,follower的lastIndex应该等于prevLogIndex。
  • prevLogTerm:也是非常重要的一个参数,和prevLogIndex一起用的,因为可能过期的leader之前给这个follower发送过一些未apply的消息,所以仅仅靠preLogIndex是无法确认leader之前的消息和follower当前最后的消息是一样的。而prevLogTerm和prevLogIndex都一样,则状态肯定是一致的。
  • entries[] log:要新增加的log们,为了提升数据同步的效率,所以可能一次性发送多条log,这样提高了写的速度
  1. 结果分析:
    返回的term 要么等于leader的term,要么大于leader的term。
  • 如果term返回的比自己的要大,说明自己这个leader已经过时了,立马转换为follower的角色
  • 如果follower的term比自己小,那么follower会更新自己的term为leader Term,并且返回leader Term,但是会返回false。
  • 如果follower的term和自己一样大,也有可能数据不够而返回false,这个时候需要递减leader的nextIndex和matchIndex,最终实现数据一致性

功能

  1. 同步最新的命令,让集群所有的日志保持同步,比如发送新的log

  2. 维持心跳,避免follower造反,因为follower没有心跳会成为candidate。
    这个时候消息的entries[]是空的

  3. 发送心跳的同时,更新leader commit Index,只要半数复制成功的log,leader会更新自己的commitIndex,再apply到状态机中,再反馈客户端操作成功,最后会等待下一个心跳时间,告知所有的follower更新最新的commitIndex

  4. 新leader 初始化的空命令的心跳,特殊的心跳,新增一个log,占据一个编号,但是log的命令为空,这个心跳可以阻止其它follower和candidate继续选举,并且通过发起一个新的log,新log的commit可以一起commit之前老leader遗留给新leader的未commit的日志。

参考

Raft算法中文版(论文翻译)
https://www.cnblogs.com/linbingdong/p/6442673.html

如果你觉得对你有帮助的话,一定要点赞!

你可能感兴趣的:(Raft系列6 AppendEntries RPC(原创))