raft理論與實踐[5]-lab2c-持久化

準備工做

一、閱讀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

參考資料

github.com/dreamerjacks

相關文章
相關標籤/搜索