mit6.824lab2A Raft
写在前面
最近更新的可能会比较慢,因为分布式系统这个部分到目前还是为爱发电。上个月是在开学考试的阶段,接下来可能会受一些项目或者学习课程安排上的影响,不过这个内容会坚持下去的。
lab2A的内容主要是关于Raft中server选举的实现,论文中的Figure2以伪代码的格式给出了很多较为详尽的解释,没有出大问题的话我打算跟着Figure2的框架来进行操作。lab2A在分析过程中看了中文的翻译解释版(英语水平有点烂),po一下。
Figure 2:
整体架构
Raft结构体是每一个server都具备一个的,作为状态机的存在。每一个server就本质上并无差距,只是其所处的状态机的状态不同。
- 我们定义了三种状态:Follower, Candidate, Leader。
- RPC通信的方式定义两种:AppendEntries RPC, RequestVote RPC。(采用sendXXX()调用其他server的XXX()方法,例如sendAppendEntries_RPC)
- 定义时钟检查Timer:electionTimer, heartbeatTimer
论文中的Figure 4较为形象地表示了这个过程,Figure 5则是从时间的维度上看的:
状态对应的产生事件
-
Follower:
处理AppendEntries RPC
处理RequestVote RPC
electionTimer
超时 -
Candidate
处理AppendEntries RPC
处理RequestVote RPC
electionTimer
超时
发起投票sendRequestVote
-
Leader
处理AppendEntries RPC
处理RequestVote RPC
electionTimer
超时
heartbeatTimer
超时
发送更新心跳包sendAppendEntries
冲突避免
AppendEntries RPC
和RequestVote RPC
是处在一个新go routine之中的,为了防止同时调用产生互斥,用mutex锁一下保平安。
对于electionTimer
和heartbeatTimer
,在生成Raft实例的时候多生成一个go routine,之后我们采用选择切换的方式处理timer的timeout定时事件,并行调用sendAppendEntries
和sendRequestVote
。
Access
Accessed in 2023/10/6 15:30(UTC +8:00)
Test (2A): initial election ...
... Passed -- 3.1 3 46 5618 0
Test (2A): election after network failure ...
... Passed -- 4.5 3 106 8244 0
Test (2A): multiple elections ...
... Passed -- 5.4 7 534 43952 0
PASS
ok 6.5840/raft 12.963s
改动部分
结构体改动部分:Raft, RequestVoteArgs, RequestVoteReply, AppendEntriesArgs, AppendEntriesReply
新增函数:convertTo(转换状态), AppendEntries, sendAppendEntries(仿照Request...), broadcastHeartbeat(要锁), startElection(要锁), randTimeDuration(raft不等要求)
之后就是在文件raft.go
中代码有提示需要在加"Your code here (2A)"的地方加了,都是对于原有的函数功能的实现。