一、实验说明
https://pdos.csail.mit.edu/6.824/labs/lab-raft.html
二、梳理
Part C要求Raft的服务器重新启动,则应在停止的位置恢复服务,Raft保持持久状态,使其在重启后能够重新运行。
代码中已经预留出了persist()和readPersist(),根据论文可以得知需要保存currentTerm, votedFor, snapshottedIndex三个变量
func (rf *Raft) persist() {
w := new(bytes.Buffer)
e := labgob.NewEncoder(w)
e.Encode(rf.currentTerm)
e.Encode(rf.votedFor)
e.Encode(rf.logs)
data := w.Bytes()
rf.persister.SaveRaftState(data)
}
func (rf *Raft) readPersist(data []byte) {
if data == nil || len(data) < 1 { // bootstrap without any state?
return
}
r := bytes.NewBuffer(data)
d := labgob.NewDecoder(r)
var currentTerm, votedFor int
var logs []LogEntry
if d.Decode(¤tTerm) != nil ||
d.Decode(&votedFor) != nil ||
d.Decode(&logs) != nil {
DPrintf("%v fails to recover from persist", rf)
return
}
rf.currentTerm = currentTerm
rf.votedFor = votedFor
rf.logs = logs
}
readPersist()
- Make()初始化的时候添加
rf.mu.Lock()
rf.readPersist(persister.ReadRaftState())
rf.mu.Unlock()
persist()
AppendEntries()和RequestVote()结束时
- Start()新增LogEntry 时
- send
AppendEntries返回term大于当前term
sebdRequestVote返回term大于当前term