TinyKV Project 3A
目录
在Raft层实现领导者转移和成员变更(虽然Raft层实现简单,但是存在很多细节问题需要注意,后面3B的测试问题一半都来自Raft层)
领导者转移
HandleTransferLeader
检查目标节点是否在集群当中,如果不在直接返回
如果当前节点不是leader,转发给Leader后返回
r.leadTransferee = m.From
接收该请求
- 检查目标节点的日志是否最新,如果不是则
sendAppend
,而后返回(等后续HandleAppendResponse
来进一步处理 - 如果目标节点的日志已经最新,发送
TimeoutNow
消息给它,让其立即开始选举;最后将leadTransferee置为None
- 检查目标节点的日志是否最新,如果不是则
HandleAppendResponse
当转移的目标节点日志不是最新时,HandleTransferLeader不能立即发送TimeoutNow
消息,而是sendAppend
使目标日志最新,这时需要在HandleAppendResponse中增加发送TimeoutNow
和重置r.leadTransferee
的逻辑。
注意,当
leaderTransferee != None
时,即在领导这转移过程中,不接受Propose请求,避免循环。
成员变更
Raft层的逻辑十分简单,主要是针对r.Prs
的修改。
|
|
notice
- 当
removeNode
时,由于集群成员数量发生变化,Leader要尝试推进日志的提交 - PendingConfIndex是一个值得注意的变量。当其不为None时,代表目前正有confChange发生,不再接收新的confChange请求,因此要在
HandlePropose
中做一定的检查。判断条件为r.PendingConfIndex != None && r.PendingConfIndex > r.RaftLog.applied
,代表存在尚未应用的confChange。