Raft协议

Raft 协议是一种分布式一致性协议,主要用于实现多个节点之间的一致性,为系统提供强一致性保证。本文描述了 Raft 的四种角色、选举机制、日志复制机制以及 Learner 角色的用途和场景。


Raft 协议的角色

在 Raft 协议中,一个节点可以处于以下四个角色之一:

  1. Follower(跟随者)

    • 默认状态,每个节点在初始阶段或者重新加入集群时都会处于该状态。
    • 被动接收来自 Leader 的心跳包(heartbeat)或日志更新请求。
    • 如果一段时间(Election Timeout)内没有接收到 Leader 的心跳包,会转变为 Candidate。
  2. Candidate(候选者)

    • 当一个 Follower 超过 Election Timeout 没有接收到心跳包时,会变为 Candidate 并发起选举。
    • 向其他节点广播请求投票(RequestVote)。
    • 如果获得超过半数的节点投票,即成为 Leader。
    • 如果选举超时且没有节点获胜,会重新开始下一轮选举。
  3. Leader(领导者)

    • 集群中的核心角色,处理客户端请求,管理日志复制并维持系统一致性。
    • 定期向 Follower 发送心跳包,表明自己是当前的 Leader。
    • 负责接收并提交客户端的写操作(通过日志复制机制实现)。
  4. Learner(学习者)

    • 一个特殊角色,负责接收日志更新但不参与选举或投票。
    • 通常用于读取副本(read-only replica),主要目的是增加系统的容错性和可扩展性。
    • 在一些场景下,Learner 扮演只读节点的角色,例如为了避免对选举过程产生影响,同时满足读扩展需求。

Raft 的 Leader 选举

起初,所有节点的状态都是 Follower。每个 Follower 都会设置一个随机的 Election Timeout,当这个时间段内没有收到 Leader 的心跳包时,将会发起选举。选举机制如下:

  1. 依次选举:

    • 某个节点首先触发选举状态,变为 Candidate。
    • Candidate 向其他节点广播请求投票的消息(RequestVote)。
    • 其他节点根据候选者的任期(term)和日志完整性决定是否投票给该候选者。
    • 如果 Candidate 获得集群中过半数节点的选票,则当选 Leader,并开始发送心跳包。
  2. 冲突处理:

    • 如果两个或多个节点同时发起选举,且得票数相同,最终导致没有节点获得多数投票,则会进入下一轮选举。
    • 在进入下一轮选举时,每个节点会重新设置一个随机的 Election Timeout,从而减少下一次选举冲突的概率。
  3. Leader 的权威性:
    当 Leader 当选后,会定期发送心跳包(AppendEntries RPC)。如果其他节点接收到心跳包,则会重置自己的 Election Timeout,确保不会触发新一轮选举。


Raft 的日志复制机制

当集群中选出了 Leader 后,Leader 开始接收客户端的请求,并通过日志复制机制(Log Replication)确保所有节点状态一致。

弱一致性:

  1. 客户端发送请求到 Leader。
  2. Leader 将操作记录为日志条目,并将其同步到所有 Follower 节点的日志中。
  3. 一旦操作被写入 Leader 的日志,Leader 会直接向客户端返回确认。
  4. Leader 后续再通知 Follower 提交(Commit)该日志操作。
    • 弱一致性具有较低的延迟,但无法保证所有节点都立即同步完成。

强一致性:

  1. 客户端发送请求到 Leader。
  2. Leader 将操作记录到自身的日志,然后将该日志条目复制到 Follower 节点。
  3. Follower 收到日志条目后,会向 Leader 发送确认(ack)信息。
  4. 当 Leader 收到大多数(过半数)节点的确认后,Leader 可以提交(commit)该日志操作,并将结果返回客户端。
    • 通过等待大多数节点的确认,确保一致性(即强一致性)。

总结:为了在不同场景下平衡性能和一致性要求,弱一致性和强一致性可以根据系统需求进行选择。


为什么需要 Learner?有什么应用场景?

1. 什么是 Learner?

Learner 是 Raft 协议中一个特殊的角色:

  • Learner 节点被设计为一个只读节点(Read-Only)。
  • Learner 不参与选举过程,也不会被要求投票。
  • Learner 只接收 Leader 发送的日志复制数据,只用作数据同步,用于扩展系统的读性能或提升容错性。

2. Learner 的应用场景:

  • 非核心节点:
    在一个分布式系统中,为了扩展读取性能,我们可能希望新增更多副本节点。但这些节点不一定需要参与选举和投票。采用 Learner 角色可以减轻选举过程的压力,并不会直接影响一致性协议的核心流程。

  • 数据同步:
    在分布式存储系统中,某些节点因为距离(比如跨地域部署)或硬件性能问题无法及时响应,但仍需要同步集群的最新日志状态。Learner 可以被用作这样的从属节点。

  • 新节点加入:
    通过 Learner 角色将新节点加入到集群中,可以避免直接参与选举和投票所带来的干扰,并且在数据同步完成后,节点可以变为 Follower 正式加入集群。

  • 备份和容灾:
    Learner 节点可以被用于构建灾备集群。其日志内容与主集群一致,在灾难发生时可以切换为 Leader,以实现数据恢复和服务接管。

  • 读扩展:
    通过增加 Learner 节点,可以显著提升系统的读性能,因为这些节点专用于处理只读请求而不会承担写操作(日志复制除外)。


Raft协议
https://mfzzf.github.io/2025/03/13/Raft协议/
作者
Mzzf
发布于
2025年3月13日
许可协议