一、特性

Raft 是一种用来管理日志复制的一致性算法

  • 复杂度低
  • 易于实现

二、设计目标

  • 必须提供完整而实际的基础来进行系统构建,从而大大减少开发人员的设计工作
  • 必须在所有条件下都是安全的,并且在典型的操作条件下可用
  • 常用操作必须是高效的
  • 易于理解,能让大多数人理解
  • 让人有直观的理解,容易扩展

三、The Raft consensus algorithm

3.1 Basic

服务器有三种状态:

  • Follower 被动的只是响应来自领导人和候选人的请求
  • Candidate 被选出一个新的Leader
  • Leader 处理所有来自客户端的请求(如果一个客户端与追随者进行通信,追随者会将信息发送给领导人)

server states

算法将时间分为不同长度的任期(Term):

  • 每个term中包含两个阶段:election,operation
  • termId是一个连续的整数,单调递增
  • 每次通信更新为最新的termId
  • 拒绝包含过期的termId的请求 raft term

RPC类型(服务器间的通信接口):

  • RequestVote
  • AppendEntries
  • InstallSnapshot

3.2 Leader election

heartbeat

  • heartbeat:不带有任何日志条目的 AppendEntries RPC
  • Leader周期性的广播heartbeat,维持Leader的地位
  • 随机的选举超时时间
  • 一台服务器最多能给一个候选人投票,先到先服务原则(first-come-first-served)
  • 获得半数以上server的投票转为Leader,广播heartbeat
  • 收到来自其他服务器发来的声明其为领导人的 AppendEntries RPC,且term大于等于currentTerm,则变为Follower,否则维持Candidate
  • 选举超时(每个server的超时时间不同),自增currentTerm,重新开始选举

3.3 Log replication

  • 客户端发出命令
  • Leader写日志,并发给Follower
  • 发给多数Follower后,将数据commit到状态机
  • 返回给客户端结果,通知Follower执行commit

log不一致: Leader通过强制Follower复制它的日志来处理日志的不一致

志匹配原则(Log Matching Property): 不同机器的日志中的两个条目有着相同的索引和任期号

  • 则它们所存储的命令是相同的。
  • 则它们之间的所有条目都是完全一样的。

3.4 Safety

  • 选举安全原则(Election Safety 一个任期(term)内最多允许有一个Leader被选上

  • 领导人只增加原则(Leader Append-Only) Leader永远不会覆盖或者删除自己的日志,它只会增加条目

  • 日志匹配原则(Log Matching) 如果一个日志条目在一个给定任期内被提交,那么这个条目一定会出现在所有任期号更大的Leader中

  • 状态机安全原则(State Machine Safety) 如果一个服务器已经将给定索引位置的日志条目应用到状态机中,则所有其他服务器不会在该索引位置应用不同的条目 领导人完全原则(Leader Completeness)

  • 选举限制:

    • 候选人的日志至少和大多数服务器上的日志一样新(up-to-date)
    • Raft 通过比较日志中最后一个条目的索引和任期号来决定两个日志哪一个更新

3.5 Follower and candidate crashes

  • Raft 中的 RPC 都是幂等
  • 重试上一个RPC,直到成功

3.6 Timing and availability

broadcastTime ≪ electionTimeout ≪ MTBF

  • broadcastTime 一台服务器并行的向集群中的其他服务器发送 RPC 并且收到它们的响应的平均时间 broadcastTime应该比electionTimeout小一个数量级
  • electionTimeout 选举超时时间 electionTimeout也要比MTBF小几个数量级
  • MTBF 单个服务器发生故障的间隔时间的平均数

四、Cluster membership changes

五、Log compaction

  • 快照(snapshot)是最简单的压缩方式
  • 状态机可以使用和快照相同的接口来实现 LSM tree
  • 每个服务器独立创建snapshot
  • 对于落后太多数据的Follower, Leader通过InstallSnapshot更新它的快照(snapshot)是最简单的压缩方式

snapshot包含一些元数据(meta data):

  • 最后被包含的索引(last included index) 指的是被快照取代的最后的条目在日志中的索引值
  • 最后被包含的任期(last included term) 指的是该条目的任期号

六、Client interaction

  • 客服端随机选一个服务器
  • 服务器返回Leader地址
  • 客服端发送数据给Leader
  • 客户端失败后重试

为了防止数据被重复提交:

客户端对于每一条指令都赋予一个唯一的序列号。然后,状态机跟踪每条指令最新的序列号和相应的响应。如果接收到一条指令,它的序列号已经被执行了,那么就立即返回结果,而不重新执行指令。

Raft 一致性算法论文译文