书接上文Raft Part B | MIT 6.824 Lab2B Log Replication。
实验准备
- 实验代码:
git://g.csail.mit.edu/6.824-golabs-2021/src/raft
- 如何测试:
go test -run 2C -race
- 相关论文:Raft Extended
- 实验指导:6.824 Lab 2: Raft (mit.edu)
实验目标
- 完成
persist()
和readPersist()
函数,编码方式参照注释。 - 优化
nextIndex[]
回退方式,否则无法通过所有测试。
一些提示
- 测试涉及服务器故障和RPC失败等不确定事件,多次运行测试确保通过。
- 需要持久化的部分包括
currentTerm
、votedFor
、log
。 - 有关
nextIndex[]
回退优化可以查看Students’ Guide to Raft。 - 在Lab2A和Lab2B中测试未能发现的错误可能会在Lab2C中暴露出来。
持久化
这部分其实很简单,代码中的注释已经很清晰了,当然你要注意data race问题。
func (rf *Raft) persist() {
w := new(bytes.Buffer)
e := labgob.NewEncoder(w)
e.Encode(rf.currentTerm)
e.Encode(rf.votedFor)
e.Encode(rf.log)
rf.persister.SaveRaftState(w.Bytes())
}
func (rf *Raft) readPersist(data []byte) {
if data == nil || len(data) < 1 {
return
}
r := bytes.NewBuffer(data)
d := labgob.NewDecoder(r)
d.Decode(&rf.currentTerm)
d.Decode(&rf.votedFor)
d.Decode(&rf.log)
}
nextIndex优化
Part B中对于失败的AppendEntries请求,让nextIndex自减,这样效率是比较慢的。
优化点1
如果 follower.log
不存在 prevLog
,让Leader下一次从 follower.log
的末尾开始同步日志。
优化点2
如果是因为 prevLog.Term
不匹配,记 follower.prevLog.Term
为 conflictTerm
。
- 如果
leader.log
找不到Term为conflictTerm
的日志,则下一次从follower.log
中conflictTerm
的第一个log的位置开始同步日志。 - 如果
leader.log
找到了Term为conflictTerm
的日志,则下一次从leader.log
中conflictTerm
的最后一个log的下一个位置开始同步日志。
nextIndex
的正确位置可能依旧需要多次RPC才能找到,改进的流程只是加快了找到正确 nextIndex
的速度。
AppendEntries中有逻辑如下。
reply.Term = rf.currentTerm
reply.Success = false
if len(rf.log)
Heartbeat中有逻辑如下。
if !reply.Success {
if reply.ConflictTerm == -1 {
rf.nextIndex[id] = reply.ConflictIndex
} else {
conflictIndex := -1
for i := args.PrevLogIndex; i > 0; i-- {
if rf.log[i].Term == reply.ConflictTerm {
conflictIndex = i
break
}
}
if conflictIndex != -1 {
rf.nextIndex[id] = conflictIndex + 1
} else {
rf.nextIndex[id] = reply.ConflictIndex
}
}
}
实验总结
Part C并不算是Raft算法的核心部分,关于nextIndex的优化本文是参照了Students’ Guide中的方式。
如果你完成了持久化和回退优化两个部分依然无法通过所有测试,那可能要仔细的检查Part A和Part B是否遗漏了某些细节。
最后,为了证明我不是在乱写,附上我的测试结果。
Original: https://www.cnblogs.com/suqinglee/p/15549998.html
Author: 李素晴
Title: MIT 6.824 Lab2C Raft之持久化
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/611816/
转载文章受原作者版权保护。转载请注明原作者出处!