基于Raft共识协议的KV数据库
基于 Raft 共識協議的 KV 數據庫
項目介紹
分布式一致性是構建容錯系統的基礎,它使得一些機器可以構成集群工作,并容許其中一些節點失效。Raft 是一個比較常見的分布式共識協議,Raft 首先選舉出一個 server 作為 Leader,然后賦予它管理日志的全部責任。Leader 從客戶端接收日志條目,復制給其他 server,并告訴他們什么時候可以安全的將日志條目應用到自己的狀態機上。擁有一個 Leader 可以簡化 replicated log 的管理。例如,leader 可以決定將新的日志條目放在什么位置,而無需詢問其他節點,數據總是簡單的從 leader 流向其他節點。Leader 可能失敗或者斷開連接,這種情況下會選出一個新的 leader。具體的算法細節可以參考論文《In search of an Understandable Consensus Algorithm》。
本項目基于 Raft 分布式共識協議,實現一個簡單 KV 數據庫。該數據庫支持 3 個操作,即 GET、PUT、APPEND。GET 操作能夠獲取一個 Key 對應的 Value。PUT 操作能夠將一個 Key 對應的 Value 寫入。APPEND 操作能夠將參數中的 Value 追加寫入的一個 Key 對應的 Value 上。
系統架構
每一個 server 都有一個日志保存了一系列的指令,state machine 會順序執行這些指令。每一個日志都以相同順序保存著相同的指令,因此每一個 state machine 處理相同的指令,state machine 是一樣的,所以最終會達到相同的狀態及輸出。
保證 replicated log 的一致是一致性算法的任務。server 中的一致性模塊接收客戶端傳來的指令并添加到自己的日志中,它也可以和其他 server 中的一致性模塊溝通來確保每一條 log 都能有相同的內容和順序,即使其中一些 server 宕機。 一旦指令被正確復制,就可以稱作 committed。每一個 server 中的狀態機按日志順序處理 committed 指令,并將輸出返回客戶端。
源碼分析
客戶端代碼:
以 GET 操作為例。因為一個集群中,只有成為 Leader 的服務器能夠處理用戶的請求,所以客戶端在發送請求給服務器時會緩存 Leader 的信息。如果返回的錯誤是 NotLeader,就會進行重試,將請求發給其他的服務器。
服務器代碼:
同樣以 GET 操作為例,服務器在接受到 Get 請求時,會檢查自己是否是 Leader,如果是的話就注冊一個回調函數。在另一個循環中,服務器會監聽成功 Commit 的 Raft 日志,并返回 GET 的結果給客戶端。
Raft 模塊代碼:
Raft 模塊是最復雜的地方,其實現參考論文中的描述:
在 Raft 層,一共有三種 RPC 調用,即 sendRequestVote, sendAppendEntries, sendInstallSnapshot。其中 sendRequestVote 用來競選 Leader,sendAppendEntries 用來同步 Raft 日志以及發送心跳sendInstallSnapshot 用來進行快速恢復。
測試部分
為了驗證 Raft 分布式共識算法實現的正確性已經服務器能夠正確處理地處理來自客戶端的請求,項目中有大量的測試用例。這些測試會模擬各種各樣服務器宕機,網絡隔離的情況。該 KV 數據庫能夠全部通過這些測試。
測試會模擬各種各樣服務器宕機,網絡隔離的情況。該 KV 數據庫能夠全部通過這些測試。
總結
以上是生活随笔為你收集整理的基于Raft共识协议的KV数据库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图片上传时报403问题
- 下一篇: SOTA 激光相机标定velo2cam_