实验准备
- 实验代码:
git://g.csail.mit.edu/6.824-golabs-2021/src/raft
- 如何测试:
go test -run 2A -race
- 相关论文:Raft Extended Section 5.2
- 实验指导:6.824 Lab 2: Raft (mit.edu)
实验目标
实现Raft算法中Leader Election(RequestVote RPC
)和Heartbeats(AppendEntries RPC
)。确保只有一个Leader被选中,且若无错误该Leader会一直唯一存在,当该Leader下线或发生其他错误导致发出的数据无法被成功接收,则会产生新的Leader来替代。
一些提示
- 参考论文的Figure 2实现相应的结构体和函数。
- 通过
Make()
创建一个后台goroutine,用于一段时间(election timeout
)没收到其他节点的消息时,通过RequestVote RPC
发起选举。 - 尽量保证不同节点的
election timeout
不会让他们在同一时间发起选举,避免所有节点只为自己投票,可以通过设置随机的election timeout
来实现。 - 测试要求Hearbeats频率每秒不高于10次。
- 测试要求New Leader在Old Leader下线后5秒内出现,考虑到一次换届多轮选举的情况(提示3的情况),election timeout应当足够短。
- 论文中对于
election timeout
设定在150ms - 300ms之间,前提是Heartbeat频率远远超过150ms一次。由于提示4的限制,实验中election timeout
应该更大。 - 推荐使用
time.Sleep()
而不是time.Timer
或time.Ticker
来实现定期或延迟行为。 - 不要忘记实现
GetState()
。 - 使用
rf.killed()
判断测试是否关闭了该节点。 - RPC相关结构字段都应使用大写字母开头,这和Go语言的语法有关。
Raft简介
日志被理解为来自客户端的请求序列,在一个集群中,有唯一的一个节点用于接收客户端请求,称为"Leader Node",为了保证数据的安全性,"Leader Node"的日志应该复制给若干个节点用于备份,称为"Follower Node"。"Follower Node"的日志需要和&