Raft一致性算法( 四 )


在展示一致性算法之后,这一章节会讨论一些可用性的问题和计时在系统中的作用 。
状态:
所有服务器上的持久性状态
(在响应 RPC 请求之前,已经更新到了稳定的存储设备)
参数
解释
currentTerm
服务器已知最新的任期(在服务器首次启动时初始化为0,单调递增)
votedFor
当前任期内收到选票的 candidateId,如果没有投给任何候选人 则为空
log[]
日志条目;每个条目包含了用于状态机的命令,以及领导人接收到该条目时的任期(初始索引为1)
所有服务器上的易失性状态
参数
解释
commitIndex
已知已提交的最高的日志条目的索引(初始值为0,单调递增)
lastApplied
已经被应用到状态机的最高的日志条目的索引(初始值为0,单调递增)
领导人(服务器)上的易失性状态
(选举后已经重新初始化)
参数
解释
nextIndex[]
对于每一台服务器,发送到该服务器的下一个日志条目的索引(初始值为领导人最后的日志条目的索引+1)
matchIndex[]
对于每一台服务器,已知的已经复制到该服务器的最高日志条目的索引(初始值为0,单调递增)
追加条目(AppendEntries)RPC:
由领导人调用,用于日志条目的复制,同时也被当做心跳使用
参数
解释
term
领导人的任期
leaderId
领导人 ID 因此跟随者可以对客户端进行重定向(译者注:跟随者根据领导人 ID 把客户端的请求重定向到领导人,比如有时客户端把请求发给了跟随者而不是领导人)
prevLogIndex
紧邻新日志条目之前的那个日志条目的索引
prevLogTerm
紧邻新日志条目之前的那个日志条目的任期
entries[]
需要被保存的日志条目(被当做心跳使用时,则日志条目内容为空;为了提高效率可能一次性发送多个)
leaderCommit
领导人的已知已提交的最高的日志条目的索引
返回值
解释
term
当前任期,对于领导人而言 它会更新自己的任期
success
如果跟随者所含有的条目和 prevLogIndex 以及 prevLogTerm 匹配上了,则为 true
接收者的实现:
 

  1. 返回假 如果领导人的任期小于接收者的当前任期(译者注:这里的接收者是指跟随者或者候选人)(5.1 节)
  2. 返回假 如果接收者日志中没有包含这样一个条目 即该条目的任期在 prevLogIndex 上能和 prevLogTerm 匹配上
    (译者注:在接收者日志中 如果能找到一个和 prevLogIndex 以及 prevLogTerm 一样的索引和任期的日志条目 则继续执行下面的步骤 否则返回假)(5.3 节)
  3. 如果一个已经存在的条目和新条目(译者注:即刚刚接收到的日志条目)发生了冲突(因为索引相同,任期不同),那么就删除这个已经存在的条目以及它之后的所有条目 (5.3 节)
  4. 追加日志中尚未存在的任何新条目
  5. 如果领导人的已知已提交的最高日志条目的索引大于接收者的已知已提交最高日志条目的索引(leaderCommit > commitIndex),则把接收者的已知已经提交的最高的日志条目的索引commitIndex 重置为 领导人的已知已经提交的最高的日志条目的索引 leaderCommit 或者是 上一个新条目的索引 取两者的最小值
 
请求投票(RequestVote)RPC:
由候选人负责调用用来征集选票(5.2 节)
参数
解释
term
候选人的任期号
candidateId
请求选票的候选人的 ID
lastLogIndex
候选人的最后日志条目的索引值
lastLogTerm
候选人最后日志条目的任期号
返回值
解释
term
当前任期号,以便于候选人去更新自己的任期号
voteGranted
候选人赢得了此张选票时为真
接收者实现:
 
  1. 如果term < currentTerm返回 false (5.2 节)
  2. 如果 votedFor 为空或者为 candidateId,并且候选人的日志至少和自己一样新,那么就投票给他(5.2 节,5.4 节)
 
所有服务器需遵守的规则:
所有服务器:
 
  • 如果commitIndex > lastApplied,则 lastApplied 递增,并将log[lastApplied]应用到状态机中(5.3 节)
  • 如果接收到的 RPC 请求或响应中,任期号T > currentTerm,则令 currentTerm = T,并切换为跟随者状态(5.1 节)
 
跟随者(5.2 节):


推荐阅读