AppBoxFuture的存儲引擎依賴Raft一致性協議來保證各個分區副本的一致性,如果不處理Raft日誌將不斷增長,因此需要特定的機制(定期或每處理一定數量的日誌)來回收那些無用的日誌數據。通過學習Raft協議內的Log Compaction,並參考TiKV等實現,作者初步 ...
AppBoxFuture的存儲引擎依賴Raft一致性協議來保證各個分區副本的一致性,如果不處理Raft日誌將不斷增長,因此需要特定的機制(定期或每處理一定數量的日誌)來回收那些無用的日誌數據。通過學習Raft協議內的Log Compaction,並參考TiKV等實現,作者初步實現了分區快照與日誌截斷回收功能。
一、快照流程:
每個分區對應一個Raft組,由不同的Raft節點分佈在集群的不同機器上,每個RaftNode都在迴圈處理Ready(如下圖所示):
在達到快照創建條件時(上圖步驟6),即滿足一定周期(如6小時)且期間應用的已遞交日誌數量達到閾值(如10000條),RaftNode通知對應的狀態機創建快照,這裡主要是利用RocksDB的Snapshot及SstFileWriter將當前分區所涉及的KV數據寫入相應的sst文件內。在狀態機創建快照成功後,RaftNode通知對應的RaftStorage截斷並回收日誌,由於目前Raft日誌同樣使用RocksDB存儲,所以可以利用RocksDB的DeleteRange功能批量刪除無用的日誌。
如果同一Raft組內的某一節點所在的機器Down機了較長的時間,在此期間此組內的Leader達到快照條件創建了快照並回收了日誌。之後Down掉的機器重新啟動,Follower與Leader通信後要求追加Down機期間的日誌,但Leader快照前的日誌已刪除,Leader會發送Raft快照給Follower,這裡需要註意的是Leader先發送狀態機創建的各個sst文件,都發送完了再發送RaftSnapshot消息。
Follower在收到快照消息時(上圖步驟3),先清理當前分區所涉及的所有舊數據,然後通知對應的狀態機恢復快照數據,這裡主要是利用RocksDB的IngestExternalFile將各個sst文件快速導入存儲內。
創建與接收的快照文件目前存儲在運行時snapshot目錄內。
二、簡單測試:
1. 啟動集群並新建測試用實體模型
參考前篇“告別單體架構,迎接分散式時代”啟動一個新集群,並且登錄至IDE創建新實體。
2. 關閉集群某一節點模擬Down機
直接Control+C關閉某一節點。
3. 新建一個服務插入5000條記錄
在IDE內新建服務用於插入5000條記錄(用於觸發快照條件),調用此服務後可看到控制台輸出如下圖所示的創建快照日誌。
4. 重新啟動Down機節點
通過如下命令重啟Down機節點,可看到控制台輸出如下圖所示的恢復快照日誌。
sudo ./appbox
5. 驗證Down機節點快照恢復
通過tools/dbscan工具查看快照數據是否已恢復。
tools/dbscan --db=data(數據所在目錄) --cf=TableCF --take=10000 --prefix=000020017000
dbscan的參數--prefix=十六進位字串, 可以只匹配相同首碼的KV記錄
三、本篇小結:
本篇介紹了Raft快照及日誌截斷回收的流程及相應的測試,GitHub上的運行時已更新可供測試。作者單獨開發AppBoxFuture到十月一日就整一年了,期間曾多次想放棄,好在頂著巨大的壓力總算解決了這最後一個技術難點,到此基本上原型驗證是沒有大問題了,下一步的重點是完善必要功能、穩定性及性能優化,並且考慮是開源該項目還是商業化運作。