Raft分布式共识系统的核心是角色状态机、心跳与选举触发、日志复制流程三大骨架;节点仅含Follower/Candidate/Leader三种状态,由Term和超时驱动迁移;心跳间隔100–200ms,选举超时150–300ms随机值;Leader需多数节点落盘后才提交日志。

用Go语言实现基于Raft协议的分布式共识系统,关键不在堆砌代码,而在于抓住三个骨架:角色状态机、心跳与选举触发、日志复制流程。只要这三块立得住,整个系统就能跑通、可调试、易扩展。
节点角色与状态管理
Raft节点只有三种合法身份:Follower、Candidate、Leader。它们不是静态标签,而是由任期(Term)和超时机制驱动的状态迁移结果。每个节点必须维护:
- currentTerm:全局单调递增的整数,每次发起选举就+1;旧Term的消息会被直接拒绝,这是防“脑裂”的第一道防线
- votedFor:本Term内只允许投一票,且一旦投票就不能反悔;初始化为"",投给自己时设为自身ID
- state:用int常量(Follower=0, Candidate=1, Leader=2)比字符串更轻量,也利于原子操作和日志序列化
心跳与选举超时设计
Follower不主动做事,只等心跳;心跳断了,它才启动选举——这是Raft“被动优先”哲学的体现。
- 心跳间隔建议设为100–200ms,选举超时设为150–300ms的随机值,避免多个节点同时超时导致分裂投票
- 选举启动时,节点先自增Term、切换为Candidate、投自己一票,再并发向所有Peer发
RequestVoteRPC - 收到响应后用
atomic.AddInt32安全累加票数;得票过半(> len(peers)/2)立即转为Leader,并启动心跳协程
日志复制与提交逻辑
Leader不是“发号施令”就完事,它必须确保命令被多数节点落盘后才敢告诉客户端“成功”。
立即学习“go语言免费学习笔记(深入)”;
- 每条日志含
Index(全局唯一序号)、Term(写入时的任期)、Data(实际命令,如set key=value) - Leader追加新日志到本地数组后,立即并发向所有Follower发送
AppendEntries;Follower校验Term和前一条日志匹配后才接受 - Leader统计成功响应数,一旦达到多数,就更新
CommitIndex;后续心跳中带上该索引,推动所有节点应用已提交日志
通信与启动脚本示例
用Go标准库net/rpc即可支撑基础RPC,无需引入第三方框架。启动两个节点做最小验证:
- 节点A:
go run main.go --id=A --peers=B --addr=localhost:8080 - 节点B:
go run main.go --id=B --peers=A --addr=localhost:8081 - 两者通过
rpc.Register暴露RequestVote和AppendEntries方法,用rpc.DialHTTP建立连接


















