共识协议Raft | 青训营笔记

136 阅读3分钟

共识算法Raft

这是我参与「第五届青训营 」伴学笔记创作活动的第20天。昨天青训营所讲的分布式理论涉及到了一些共识算法比如RaftPaxos,但讲的比较笼统,该文章将进一步讨论Raft协议,包括其基本流程、实现的细节以及一些工程优化。

基本流程

Raft是为了保证分布式集群中所有机器的强一致性多提出的一个共识算法。该算法的实现要满足一个复制状态机(Replicated state machines) 的前提:就是集群的每个节点都会存储一个包含一系列指令的日志,按照顺序执行该日志的指令,节点就会到达一个确定的状态,如果所有节点都复制了相同的日志且初始状态一致,那么这些节点就一定会到达相同的状态。满足了这个前提,Raft的任务就从保证节点状态的一致性转为了保证节点所复制的日志的一致性。为了实现这一目的,Raft协议的设计分成了三个部分:领导人选举日志复安全性

一些基本概念

节点的状态:

  • 领导人(Leader):由集群投票选举出的节点,该节点的日志比集群中过半节点的日志条目要新,Leader负责将日志同步给其他节点并根据其他节点的反馈决定日志是否提交;
  • 候选者(Candidate):集群中没有Leader时Follower会转成Candidate,发起投票请求来选举出Leader;
  • 跟随者(Follower):只负责接收Leader的消息,同步Leader的日志更新自己的状态; 其他的一些概念:
  • 任期(Term):每个Leader都会有一个任期,当候选者发起投票请求时任期加一;
  • 选举超时时间(Election Timeout):当Follower在该时间内没有收到Leader的请求,那么将会转成Candidate,发起新一轮投票;
  • 心跳时间(Heartbeat Time):Leader会周期性的向Follower发送心跳消息以巩固自己的Leader地位。 节点的状态转化如下图所示: image.png

节点的状态

集群中的每个节点都存储着以下信息来表示节点当前的状态:

所有服务器的持久状态信息
currentTerm当前的任期,指该节点认为的最新任期
voteFor该任期内获得选票的候选人(如果还没投的话为空)
log[]节点的日志条目,每个条目包含状态机的指令和收到时的任期
网络安全保护对象的重要程度 网络安全保护对象可能受到损害的程度
所有服务器的非持久状态信息
commitIndex已被提交的最高日志索引
lastApplied已经应用于该状态机的最高日志索引(一般情况下lastApplied<=commitIndex)
Leader节点的非持久状态信息(需要在领导人选举完成后初始化
nextIndex[]对于每个服务器,要发送给该服务器的下一个日志条目索引(初始为Leader的len(log[])+1
matchIndex[]对于每个服务器,已知在服务器上复制的最高日志条目的索引(初始为0,选举完后的第一轮心跳会更新)
网络安全保护对象的重要程度
currentTerm 当前的任期,指该节点认为的最新任期