iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 15
1
Software Development

服務開發雜談系列 第 15

etcd Raft淺談(下) 日誌複製

Raft日誌複製Log Replication

當etcd收到Client發出的操作請求時, 會呼叫AppendEntries把操作命令當成一個指令的Entry寫在log裡, 並標上Index.
然後再把log當成message傳送給Follower.

Follower收到log後也是會Append entry, 並且返回對應的回應訊息給Leader.

Leader一樣收到半數以上的回應後, 就把Entry給commitcommitted, 並返回操作結果給Client, 然後也把commit給包成raftlog給Append Entry.

等到下一次heartbeat發送時, 就把Entries也帶過去通知Follower們執行commit.


這時候集群的狀態就完成一致了, 這個過程就是日誌複製Log Replication

當然以上是Raft的日誌複製.
其實也很像二階段提交(2PC),
第一階段做把日誌對Folloer做日誌複製, 等過半都複製完成時, 做本地commit, 就回應給Client.
第二階段是異步的, Leader就週期性地把提交資訊透過heartbeat提交給Follower, 所以Follower們也會完成commit.

etcd組件介紹

etcd的話, 內部核心稍微複雜點

etcd Server

主要定義了etcd對client的核心接口.
還有跟內部其他模組的設定與溝通.
其中id該節點的ID
appliedINdex就是用來紀錄目前這server節點已經Apply的Entry紀錄的最大索引值.
committedIndex就是紀錄已經提交成功的Entry紀錄的索引值.
inflightSnapshots已經發送出去但還沒收到ack的快照數量.
leadElecttedTime紀錄該節點最近一次當上Leader狀態的時間戳記.
cluster目前cluster中所有節點的資訊.
snapshotter讀寫快照檔案
snapCount一個門閥值, 當目前的entry數量距離上一次快照的entry數量, 超過這閥值時, 就會觸發快照.
compactor用來控制定期壓縮的頻率
非常多配置QQ

Raft Core

實現了Raft演算法的功能, 就這三篇一直介紹的內容.

Memory Storage

主要用來儲存Raft節點臨時的資料與數據, 像是entry, snapshot, 節點狀態...etc, 還沒提交之前暫存用.
也用來存放之前提及的KeyIndex.

WAL(Write Ahead Log)

就在執行操作命令前先寫入一條日誌(很像MySQL的redo log).
這日誌會以xxxxxxxxx.wal的檔名存在於節點的文件上.
每個WAL檔案大小為64MB, 超過就會生成新的檔案, 該檔案用flock文件鎖做鎖定, 所以同時間也只有一個執行緒能操作.

SnapShotter

儲存和讀取快照用.
檔名是xxxx.snap.
如果節點當機了, 要從WAL日誌文件來復原, 很耗時.
從快照來加載, 在從快照之後的相對位置來開始讀取WAL日誌文件, 就快非常多了.
藉由EtcdSever:triggerSnapshot來決定是否觸發快照行為, 裡面會判斷SnapshotCount.

EtcdSErver:snapshot執行完快照後, 會把被載入快照的WAL檔都刪除(Storage:Release).

BoltDB

etcd V3的backend store預設使用的就是BoltDB.
這部份在之前介紹過了.

參考:
In Search of an Understandable Consensus Algorithm這份論文對Raft和日誌複製有詳細的說明.
Raft演算法動畫


接著數篇就介紹些Client API跟做點範例.


上一篇
etcd Raft淺談(中) 選舉篇
下一篇
etcd 連線基本設定與KV CRUD
系列文
服務開發雜談33

尚未有邦友留言

立即登入留言