Log persist是将raft的Log、currentTerm和voterfor这三个数据持久化存储在磁盘里,这样当系统崩溃时,我们能从磁盘中读取持久化的数据。在本文的实现中,因为是在一台电脑中通过网络模拟了分布式场景。所以,本文是通过Go的bytes.buffer实现持久化存储。
一. bytes.buffer
bytes.buffer是一个缓冲byte类型的缓冲器,其存放数据都是byte。而buffer是bytes中的一个type buffer struct{}。其是一个变长的buffer,具有read和write方法。buffer的零值是一个空的buffer,但可以使用。
但我们穿件一个buffer时,其底层就是一个[]byte,可以向里面读写数据。
二. 利用bytes.buffer实现持久化存储
func (rf *Raft) persist() {
w := new(bytes.Buffer)
e := labgob.NewEncoder(w)
e.Encode(rf.currentTerm)
e.Encode(rf.votedFor)
e.Encode(rf.log)
data := w.Bytes()
rf.persister.SaveRaftState(data)
}
type Persister struct {
mu sync.Mutex
raftstate []byte
snapshot []byte
}
func (ps *Persister) SaveRaftState(state []byte) {
ps.mu.Lock()
defer ps.mu.Unlock()
ps.raftstate = clone(state)
}
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)
rf.mu.Lock()
defer rf.mu.Unlock()
d.Decode(&rf.currentTerm)
d.Decode(&rf.votedFor)
d.Decode(&rf.log)
}