Lab 2C
lab中把这个persist 实验标成hard,单单就只是这一个实验的的代码量的话我表示有点质疑,感觉mid甚至easy比较合适,哈哈哈。当然如果需要把前面2B的正确化检测进一步的测试的话,那么还是很配当hard的。
这个mid的实验的纯代码可能要写就十分钟就写完了,但是测试还是很难全部通过,这边我们不贴全部代码了,还是很简单的。但是我还是改了好几天的bug,改bug不难 发现bug复现bug难,这里的每一个测试都可能涉及到随机上千种不同的网络环境。现在的情况是连续测试了1 h 全部通过,应该是没啥问题了。
这里就贴上 如何改进 nextIndex向前移动的代码,感觉不是很优雅,但是还是能够跑的动哈哈哈。
if len(rf.logs) < args.PreLogIndex {
reply.Success = false
if len(rf.logs) > 0 {
reply.Xterm = rf.logs[len(rf.logs)-1].CurrentTerm
reply.Xindex = rf.logs[len(rf.logs)-1].Index
} else {
reply.Xterm = -1 //代表自己没东西全部log发给我
}
DPrintf("索引过大返回false, 应该退回到%v , rf.logs长度%v", reply.Xindex, len(rf.logs))
rf.persist()
return
}
if args.PreLogIndex <= 0 {
reply.Success = true
rf.logs = rf.logs[:0]
rf.logs = append(rf.logs, args.Logs...)
rf.persist()
return
}
if rf.logs[args.PreLogIndex-1].CurrentTerm != args.PreLogTerm {
DPrintf("preIndexlog内容不一样 还需要往前移动,返回false")
reply.Success = false
reply.Term = rf.logs[args.PreLogIndex-1].CurrentTerm
reply.Xindex = 1
//向后倒退找到当前term的第一个开始的index,作为reply index
for i := args.PreLogIndex - 1; i >= 0; i-- {
if rf.logs[i].CurrentTerm == reply.Term-1 {
reply.Xindex = rf.logs[i].Index + 1
break
}
}
rf.logs = rf.logs[:args.PreLogIndex-1]
rf.persist()
}
在AppendEntriesRPC reply
中的添加 Xterm Xindex,主要是Xinex 来告诉Leader的nextIndex 该退回到哪里,然后感觉这里的Xterm作用不大(课程上面也有人提到这个的作用是什么,老师回答比较模糊,意思就是取决于你的实现),这里我吧Xterm 为-1的时候表示follower没有任何的log,也就是需要把nextIndex设置为1。
//这里是server的处理方法
if !reply.Success {
//如果回复false,那么就需要把发送的next给向前移动一位
//优化,可以根据xindex来修改nextIndex
if reply.Xterm == -1 {
rf.nextIndex[server] = 1
} else if reply.Xindex != 0 {
rf.nextIndex[server] = reply.Xindex
} else {
if rf.nextIndex[server] > 1 {
rf.nextIndex[server] = rf.nextIndex[server] - 1
}
}
DPrintf("收到false,向前移动next,now:%v", rf.nextIndex[server])
}
相比于2A与2B的实现多了几处修改的地方,代码放在这里了,可以去看看。https://github.com/greyjoy-wh/labs-of-6.824/tree/2C