一、閱讀raft論文
二、閱讀raft理論與實踐[1]-理論篇
三、閱讀raft理論與實踐[2]-lab2a
四、閱讀raft理論與實踐[3]-lab2a講解
五、閱讀raft理論與實踐[4]-lab2b日誌複製
六、查看我寫的這篇文章: 模擬RPC遠程過程調用git
若是基於Raft的服務器從新啓動,則應從中斷的位置恢復服務。 這就要求Raft保持持久狀態,使其在重啓後仍然有效。github
論文中Figure 2指出了那些字段須要持久化。golang
而且raft.go包含有關如何保存和恢復持久性狀態的示例。bootstrap
一個「真實的服務在每次Raft更改狀態時將Raft的持久狀態寫入磁盤,並在從新啓動時從磁盤讀取最新的狀態來恢復。服務器
可是咱們的實現將會採用一個結構體的方式來模擬實現persister.go。app
調用Raft.Make()會提供一個Persister,它持有Raft的最近持久狀態。ide
Raft應從該Persister初始化其狀態,並在每次狀態更改時修改其持久狀態。函數
主要使用Persister的ReadRaftState()和SaveRaftState()方法。測試
在本實驗中,咱們須要完善在raft.go中的persist() and readPersist()方法。編碼
須要使用到labgob包中的編碼與解碼函數。
你須要明確在何時須要持久化。
下面只列出兩個重要實現,其餘再也不贅述,留給讀者本身實現。
func (rf *Raft) persist() { // Your code here (2C). 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 } // Your code here (2C). r := bytes.NewBuffer(data) d:= labgob.NewDecoder(r) d.Decode(&rf.CurrentTerm) d.Decode(&rf.VotedFor) d.Decode(&rf.Logs) }
> go test -v -run=2C
https://github.com/dreamerjackson/golang-deep-distributed-lab