一致性协议

https://zhuanlan.zhihu.com/p/130974371
Raft协议动画 http://thesecretlivesofdata.com/raft/

以我个人的理解来阐述一下Raft协议:

首先,Raft协议是一个单主协议,即写操作必须经过leader,再由leader将该消息同步至各follower

那么首先就讲一下选举过程:

  1. 如果一个follower在一个随机时间内(150-300ms)没有收到来自leader的heart beat,则其成为一个candidate参与到选举中,并将自己的term值加一
  2. 然后该candidate投自己一票,然后要求集群中的其他节点给它投票
  3. 如果收到集群内半数的投票,那么它就正式成为一个leader

选举完毕后,就进入正常同步过程

  1. Client向leader发送写请求指令,leader将该请求写入日志(但没提交)
  2. leader去通知其他follower,
  3. follower收到通知后也将该请求写入日志(但没提交),并回复leader
  4. 如果 leader收到半数节点的回复,则提交之前没提交的日志,并通知其他follower也提交日志
  5. 其他follower收到后提交之前没提交的日志

那么有人可能就要问了,为什么半数同意就能达到最终一致性呢,其他小部分没收到通知的follower如何保证与其他节点的数据一致呢?

那么就考虑一下存在网络分区的情况:

  • 如果原 leader所处的分区节点数超过半数,那么其他分区肯定不能选举出新leader。导致的结果就是,该leader所处分区的日志都能正常提交,其他分区的日志仅仅被记录而不能提交。这时如果连接恢复正常,那么其他分区的节点根据日志的id,将其日志同步至与正常节点一致的状态后再重新进入正常同步阶段。
  • 如果原 leader所处的分区节点数没超过半数,那么超过半数节点的分区(如存在)则会选举出一个新leader,且该leader的term大于原leader。导致的结果就是新leader所处分区的日志都能正常提交,其他分区的日志仅仅被记录而不能提交。这时如果连接恢复正常,其他分区的节点发现正常的节点的term大于它的term,那么它就知道已经选举产生了新的leader,那么它就会将原term中未提交的日志抛弃,而更新至与新term日志一致的状态,从而达到最终一致性。
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页