Follower
集群初始状态,被动接收来自 Leader 的心跳(AppendEntries)和日志复制,以及来自 Candidate 的选票请求。
被动角色
Candidate
Follower 超时后转变而来,发起选举,向所有节点请求投票,若得到多数票则升为 Leader。
竞选角色
Leader
集群唯一主节点,负责接收客户端请求、日志复制、发送心跳维持地位。
主节点
Term(任期)
单调递增的逻辑时钟,每次选举 Term +1。节点只接受 Term ≥ 自身当前 Term 的消息。
逻辑时钟
Election Timeout
随机超时(通常 150ms–300ms),Follower 在此时间内若没收到心跳则触发选举,随机化避免同时选举。
关键参数
集群启动
所有节点以 Follower 身份启动
启动随机 Election Timeout 计时器(150–300ms)
Election Timeout 内
收到 Leader 心跳?
✓ 是(心跳正常)
重置计时器
继续监听
↩ 循环等待
✗ 否(超时)
转为 Candidate
currentTerm += 1
为自己投票
向集群中所有其他节点广播
RequestVote RPC(携带 currentTerm, candidateId, lastLogIndex, lastLogTerm)
等待投票响应 / Election Timeout 再次倒计时
✓ 是 · 赢得选举
升级为 Leader
立即发送心跳
阻止其他选举
接收客户端请求
复制日志到 Follower
定期发送 Heartbeat
平票 / 超时
随机等待后
Term += 1
重新发起选举
↩ 循环重选
✗ 收到更高 Term
立刻退回 Follower
更新 currentTerm
重置 votedFor = null
↩ 等待新心跳
收到 RequestVote(term, candidateId, lastLogIndex, lastLogTerm)
✓ 是
votedFor = null
或 = candidateId ?
授予投票
返回 true
重置 timeout
🔴 场景:5 节点集群,A、C 同时超时,产生平票
A、C 同时发起选举
Term = 2
→
A 获 B 的票
C 获 D/E 的票
各 2 票,未过半
→
双方 Election Timeout
(随机)各自超时
→
先超时的节点
Term = 3 重新选举
打破僵局
→
新 Candidate 获
多数票,成为
唯一 Leader
✅ 关键:随机化 timeout + Term 递增保证最终一定能选出 Leader,不会永久死锁。