Raft 协议是一种为了提高易理解性(Understandability)易实现性而设计的分布式共识算法(Consensus Algorithm)

在分布式系统中,为了保证“数据不丢、服务不挂”,通常会将数据复制到多台服务器上。但如果某台机器宕机或网络发生抖动,如何让所有机器对某个数据更改“达成一致”?这就是分布式共识要解决的问题。著名的 Paxos 协议虽然严谨,但极其晦涩且难以工程落地;Raft 就是为了替代 Paxos 而诞生的。

理解 Raft 协议,核心只需要抓住 “1 个目标、3 种角色、2 个核心机制”


一、 核心思想:强 Leader 模型

Raft 采用了强 Leader(Leader-Driven)的设计。简单来说,就是“一个集群,一个老大,听老大的”

  • 所有的写请求(客户的数据更新)都必须由 Leader 统一处理。
  • Leader 负责把日志(数据)复制给其他人(Follower),并决定什么时候把数据正式写入磁盘(Commit)。
  • 只要 Leader 还在且大多数机器正常,集群就能正常工作;如果 Leader 挂了,大家就重新选一个 Leader。

二、 节点的三种角色与转换

Raft 将集群中的每个节点定义为以下三种角色之一:

  1. Leader(领导者):负责处理所有客户端请求、管理日志复制,并定期给所有节点发送“心跳(Heartbeat)”来维持统治。
  2. Follower(跟随者):完全被动。不发送请求,只响应来自 Leader 和 Candidate 的请求。如果长时间没收到 Leader 的心跳,就会变身。
  3. Candidate(候选人):Leader 挂了之后,节点变成 Candidate,开始拉票准备竞选新的 Leader。

角色转换过程

Follower(超时没收到心跳) → 变成 Candidate(发起投票) → 收到半数以上选票 → 成为 Leader


三、 两个核心机制

Raft 协议把复杂的分布式一致性问题拆分成了两个核心子问题:Leader 选举日志复制

1. Leader 选举(Leader Election)

  • 任期(Term):Raft 把时间划分为一个个连续的“任期(Term)”,用递增的数字表示(如 Term 1, Term 2)。每个 Term 最多只有一个 Leader。
  • 心跳与超时:Leader 会定期向 Follower 发送心跳。每个 Follower 都有一个随机的选举超时时间(Election Timeout,通常在 150ms ~ 300ms 之间)
  • 竞选过程
  1. 如果 Follower 在超时时间内没收到心跳,它就认为 Leader 挂了。
  2. Follower 将自己的 Term 加 1,角色转为 Candidate,并向其他节点发送“请投我一票(RequestVote)”的请求。
  3. 先到先得:其他节点在一个 Term 内只能投出一票。如果某个 Candidate 获得了超过半数(Majority,如 5 台机器中的 3 台)的选票,它就成功当选为新的 Leader,并开始发送心跳宣布主权。
  4. 随机超时规避平票:因为各节点的选举超时时间是随机的,大大降低了多个节点同时发起竞选导致“平票(Split Vote)”的概率。

2. 日志复制(Log Replication)

当 Leader 选出来后,系统就可以正常处理客户端的写请求了。日志复制的完整生命周期如下:

  1. 接收请求:客户端发来写请求(如 Set X = 10),Leader 先把这条指令作为一条日志(Log)追加到自己的本地。
  2. 复制日志:Leader 通过 RPC(AppendEntries)把这条日志广播复制给所有 Follower。
  3. 提交日志(Commit):当 Leader 发现超过半数(Majority)的 Follower 已经成功把这条日志写入了本地磁盘,Leader 就会将这条日志标记为 Committed(已提交),并将其应用(Apply)到自己的状态机(把结果写入数据库/内存)。
  4. 返回响应:Leader 向客户端返回操作成功。
  5. 通知 Follower:在下一次心跳或日志复制时,Leader 会通知 Follower:“这条日志我已经 Commit 了,你们也可以应用到状态机中了”。

四、 Raft 如何保证数据安全与一致?

在分布式网络中,网络分区、节点宕机随时会发生。Raft 通过以下强约束规则保证数据绝不丢失和混乱:

  1. 选举安全性(Election Safety)
  • 拥有“最新数据”的节点才有资格当 Leader。如果 Candidate 的日志落后于某个 Follower,Follower 就会拒绝投票给它。这样保证了新 Leader 一定包含了所有已提交(Committed)的日志
  1. Leader 只追加,不修改(Leader Append-Only)
  • Leader 绝对不会覆盖或删除自己的日志,只能追加新日志。
  1. 日志匹配特性(Log Matching Property)
  • 如果两个节点上的日志在某个索引(Index)位置的 Term 相同,那么从头到这个索引为止的所有日志都完全相同。
  1. 强行覆盖不一致(Leader 优先)
  • 如果网络抖动导致某些 Follower 的日志落后或与 Leader 不一致,Leader 会强制将自己的日志复制给 Follower,覆盖掉 Follower 上不一致的部分,最终保持全网完全一致。

一句话总结

理解 Raft 协议,就记住这句话:

“通过随机超时选出唯一 Leader,Leader 接收请求并广播日志,只要过半节点落盘即算提交,始终以 Leader 的日志为准。”

课后练习

1 raft满足CAP理论中哪些项?同时给出理由

raft满足CP,缺少可用性。 原因:

  1. 当集群发生网络分区,导致某一部分节点处于“少数派分区”(节点数 ≤ N/2)时,该分区由于无法凑齐多数派,无法选举 Leader 也无法提交写日志。
  2. 处于少数派分区的健康节点在接收到写请求或强一致读请求时,会直接返回错误或超时。
  3. 由于健康节点无法正常给出成功响应,违反了 CAP 中“任意非故障节点均需返回成功响应”的定义。

在分布式系统中,“网络通信中断”不等于“节点下线/退集群”。集群的总节点数(配置文件中固定的集群规模)在运行期是静态确定的,网络分区绝对不会改变节点对“集群总数”的认知。