【MIT 6.824】lab2:Raft基本概念

44 阅读2分钟

基本概念

所有节点的持久数据:

  • currentTerm:当前节点视角的任期,初始化0
  • votedFor:当前任期给谁投的票
  • log[]:log entries,由term和command组成,第一个索引为1

所有节点的易变数据:

  • commitIndex:已知提交的最高日志项的索引
  • lastApplied:应用于状态机的最高日志项的索引

Leader的易变数据:

  • nextIndex[]:要发送到每个follwer的下一个日志条目的索引(初始化为leader最后一个日志索引+ 1)

  • matchIndex[]:对于每个服务器,已知要在服务器上复制的最高日志条目的索引(初始化为0,单调递增)

Term

任期,整数类型,初始0,raft中的时间线,用于区分过期消息。

规则:

  • 每次通信(选举、log复制)都携带Tern

  • Term自动更新机制,当发现接收请求的Term更大:

    • Follower:直接更新
    • Leader:结束当前任期,变为Follower并更新Term
    • Candidate:结束当前选举,变为Follower并更新Term

Rules for Servers

All Servers

  • 如果commitIndex > lastApplied: 增加lastApplied,则向状态机应用日志[lastApplied]
  • 如果RPC请求或响应包含term T > currentTerm:设置currentTerm = T,转换为follower

Followers

  • 回应候选人和领导的竞选请求
  • 如果超过election timeout没有收到AppendEntries或RequestVote:转换为候选人

Candidates

  • 转换为候选人后,开始选举:

    • 增加currentTerm
    • 为自己投票
    • 重置选举计时器
  • 发送RequestVote rpc到所有其他服务器

  • 如果获得大多数服务器的投票:成为领导者

  • 如果从新的leader接收到AppendEntries RPC:转换为follower

  • 如果选举超时:开始新的选举

Leaders

  • 结束选举时:发送初始空的AppendEntries rpc (心跳)到每个服务器;在空闲期间重复以防止选举超时。

  • 如果从客户端收到命令:追加条目到本地日志,在条目应用到状态机后响应

  • 如果最大 index ≥ nextIndex 发送 AppendEntries RPC 带有 entries starting at nextIndex

    • 如果成功:更新追随者的nextIndex和matchIndex
    • 如果AppendEntries因为日志不一致而失败:递减nextIndex并重试
  • 如果存在N,使得N > commitIndex