Raft协议解析:领导者选举与日志复制

引言

在分布式一致性领域,Raft协议通过清晰的角色划分与确定性流程设计,以更易理解的方式解决了多节点协同一致性的核心挑战。该协议将系统节点明确分为领导者(Leader)跟随者(Follower)候选者(Candidate)三类角色,通过心跳驱动选举日志强制同步两大核心机制,既规避了传统算法Paxos的复杂性,又保证了网络分区或节点故障时的快速恢复能力。其任期递增(Term)规则与多数派承诺(Quorum)策略,确保了集群在领导者宕机时能通过严格的选举超时竞争机制快速切换新主节点,而日志连续性校验状态机复制规则则为跨节点数据一致性提供了数学证明级别的可靠性支撑。这种兼顾可理解性与强一致性的设计,使得Raft成为Etcd、Consul等新一代分布式系统的基石性协议。

Raft协议

Raft算法核心流程可以归纳为:

  • 首先选出leader,leader节点负责接收外部的数据更新/删除请求;
  • 然后日志复制到其他follower节点,同时通过安全性的准则来保证整个日志复制的一致性;
  • 如果遇到leader故障,followers会重新发起选举出新的leader;

名词解释

三种角色

集群中每个节点只能处于Leader、Follower和Candidate三种状态的一种。

Leader:可以接受客户端的数据请求,负责日志同步。(只有Leader节点接受读写请求)

Follower:负责接受Leader同步的日志,如果刚刚开始或和leader通信超时,follower会发起选举,变成Candidate,然后去竞选leader。(不接受读写请求)

Candidate(候选):Follower发起选举后就变为candidate,会向其他节点拉选票。candidate的票会投给自己,所以不会向其他节点投票。

日志复制消息和心跳消息

心跳消息和日志复制消息都是AppendEntries RPC请求,具有相同的消息结构和通信机制。心跳消息的entries[] 字段是空的,其它和复制消息一样。follower节点并非只有收到心跳消息才会重置选举计时器,只要收到AppendEntries RPC请求都会重置选举计时器(选举计时器记录的是上次和leader通信的时间间隔)。

两个超时

heartbeat timeout是leader发送心跳的周期,election timeout是follower最多能容忍多长时间没收到心跳,如果超过election timeout没有收到心跳线程会触发选举。通常情况heartbeat timeout要小于election timeout。

选举超时(election timeout)

  • 在设置的选举超时时间内收到Leader或Candidate的心跳消息,则重启定时器,否则发起选举。

心跳超时(heartbeat timeout)

  • 领导者会定期发送心跳消息给追随者,以通知它们领导者仍然活跃。
  • 通知Follower将Leader已经提交的日志项,应用到Follower本地状态机中。

首次选举

Server启动时,各个节点初始状态均为Follower,每个节点会给自己随机设置一个选举超时时间(一般为150 ~ 300ms)。如果在各自设置的超时时间内收到来自Leader或Candidate的心跳消息,则选举计时器重启(表示已经有Leader)。否则会发起一次选举过程,向其他服务器发出选举自己的请求(先超时的节点先发起投票)。

举个例子

假设Node A、Node B、Node C 3个节点election timeout分别是200ms、210ms、150ms。

如果未收到心跳消息,Node C的election timeout首先过期,Node C会给自己投上一票,Vote Count: 1,任期Term也设置为1(每个节点的Term为0,每投一票加1)。

然后发起【选我当Leader】的请求给其他follower节点:Node A和Node B。如果在该任期内(Term = 1)其他节点都未投票,则会给Node C投票,并重置自己的election timeout;否则拒绝投票。当Node C收到大多数投票(半数以上)之后,就会成为Leader。

当Node C成为Leader之后,会以heartbeat timeout时间间隔不断发送【追加日志】的消息给Follower节点Node A和Node B,在该期间内,Node A和Node B会接收Node C的请求,追加到各自的日志中。

非首次选举

如果Follower在election timeout时间内未收到Leader发送的心跳消息,率先超时的节点就会成为candidate,重新发起选举过程。

举个例子

假设Leader 节点Node B宕机,Node A和Node C在election timeout时间内未收到Leader节点发送的消息,Node C率先超时成为Candidate,然后向其他节点发起【选我当Leader】的投票请求,并且Term任期升级为2。在任期为2的期间内,Node A未给别的投票请求作出响应,所以可以给Node C投票。Node C获取了多数选票(包括自己给自己投的一票),这样Node C就成为了新的Leader。

特殊情况

Node B和Node D同时超时成为候选者,然后同时发起投票请求,Node B和Node D在任期为4期间分别获取到Node A和Node C的投票,这样Node B和Node D获得相同票数2,无法选举出Leader,会继续等待。在下一个heartbeat timeout之后,Node C率先超时并发起投票过程,最终获取大多数票数成为新的Leader节点。


感谢您的阅读!如果文章中有任何问题或不足之处,欢迎及时指出,您的反馈将帮助我不断改进与完善。期待与您共同探讨技术,共同进步!

你可能感兴趣的:(分布式,分布式)