高级分布式系统
Raft 分布式一致性协议
etcd/Consul 如何在多节点间达成共识
分布式系统的核心难题:多个节点如何就某个值达成一致?Raft 用「选举」和「日志复制」两个机制解决:集群中只有一个 Leader 负责接收写请求,Leader 将日志条目复制到多数派 Follower 后才提交。Leader 宕机时,拥有最新日志的 Follower 通过超时选举成为新 Leader。相比 Paxos,Raft 更易理解和实现,是 etcd、Consul、TiKV 等系统的共识层基础。理解 Raft 就理解了分布式存储的「大脑」如何运作。
Raft共识协议Leader 选举日志复制etcd分布式存储
STEP_1
选举超时随机化(150-300ms)是避免活锁的关键超时触发投票,多数派胜出 — PROCESSING
leader-election.log
// Raft 选举流程(伪代码)
class RaftNode {
state: "follower" | "candidate" | "leader" = "follower"
currentTerm: number = 0
votedFor: string | null = null
onElectionTimeout() {
this.state = "candidate"
this.currentTerm++
this.votedFor = this.id
let votes = 1 // 投票给自己
// 向所有节点请求投票
for (const peer of this.peers) {
const reply = await peer.requestVote({
term: this.currentTerm,
candidateId: this.id,
lastLogIndex: this.log.length - 1,
lastLogTerm: this.log.last?.term ?? 0,
})
if (reply.voteGranted) votes++
if (votes > this.peers.length / 2) {
this.becomeLeader()
return
}
}
}
handleRequestVote(req): { voteGranted: boolean } {
// 只给日志至少和自己一样新的 Candidate 投票
if (req.term > this.currentTerm && this.isLogUpToDate(req)) {
this.votedFor = req.candidateId
return { voteGranted: true }
}
return { voteGranted: false }
}
}Leader 选举:每个节点有三种角色:Leader、Follower、Candidate。Follower 在选举超时(150-300ms 随机)内未收到 Leader 心跳,则转为 Candidate 发起选举:递增任期号(Term)、投票给自己、向其他节点发送 RequestVote RPC。收到多数派投票的 Candidate 成为新 Leader。每个 Term 最多一个 Leader,每个节点每个 Term 只投一票(先到先得)。随机超时避免多个节点同时发起选举导致的分票。
实时沙盒SANDBOX
CRITICAL
快速场景
手动调节
集群节点数
Raft 集群大小
5 节点
3 节点最小可用集群
模拟 Leader 宕机
Leader 正常运行,处理读写请求
模拟网络分区
网络正常,所有节点互通
写入延迟
日志复制的网络延迟
10 ms
低延迟,写入快速提交