您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關如何進行Raft協議實踐中的SOFAJRaft剖析,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
- SOFAJRaft 概述 -
從通過SOFAJRaft 框架的核心流程剖析加深對Raft協議的理解。SOFAJRaft 是一個純 Java 的 Raft 算法實現庫, 基于百度 braft 實現而來, 使用 Java 重寫了所有功能, 支持:
領導人選舉和基于優先級的半確定性領導人選舉。
日志復制和恢復。
快照和日志壓縮。
只讀成員(learner)。
集群成員管理,添加節點,刪除節點,替換節點等。
完全并發復制。
容錯能力。
非對稱網絡分區容忍性。
當法定人數同伴都死亡的解決方法。
管道復制
線性一致讀,ReadIndex/LeaseRead。
額外擴展了一些功能:
對稱網絡分區容忍性
重啟后的轉移領袖、負載均衡場景實現
更豐富的指標統計展示
通過Jepsen一致性驗證測試
包含嵌入式分布式KV存儲實現
整體項目如下:
- 領袖選舉 -
SOFAJRaft 的選舉主要通過判單兩個屬性:LogIndex 和 Term;Term 即任期,LogIndex即提交到 raft group 中的任務都將序列化為一條日志存儲下來,每條日志一個編號,在整個 raft group 內單調遞增并復制到每個 raft 節點。可以理解為事務id。投票處理的邏輯主要在 com.alipay.sofa.jraft.core.NodeImpl中,主要有四個函數:
處理處理預投票請求
Message handlePreVoteRequest(request)
預投票
void preVote()
處理投票請求
Message handleRequestVoteRequest(request)
投票
electSelf()
整體流程如下:
Candidate(候選人) 被 Election timeout觸發
Candidate 開始嘗試發起 pre-vote 預投票
Follower(追隨者) 判斷是否認可該 pre-vote request
Candidate 根據 pre-vote response 來決定是否發起 RequestVoteRequest
Follower 判斷是否認可該 RequestVoteRequest
Candidate 根據 response 來判斷自己是否當選
使用預投票可以防止網絡抖動等特殊原因引起的瞬時失聯節點無故搗亂:候選者在發起投票之前,先發起預投票,如果沒有得到半數以上節點的反饋,則候選者就會識趣的放棄參選,也就不會抬升全局的 Term。
投票源碼:
預投票源碼:
- 存儲機制 -
SOFAJRaft 存儲模塊分為:
Log 存儲記錄 Raft 配置變更和用戶提交任務日志,把日志從 Leader 復制到其他節點上面;
checkAndResolveConflict(entries, done)
offerEvent(done, type)
Disruptor隊列發布other類型事件
appendToStorage(toAppend)
回調事件處理器StableClosureEventHandler存儲日志
返回日志里的首/末個日志索引;
按照日志索引獲取 Log Entry 及其任期;
把單個/批量 Log Entry 添加到日志存儲;
從 Log 存儲頭部/末尾刪除日志;
刪除所有現有日志,重置下任日志索引。
LogStorage 是日志存儲實現,默認實現基于 RocksDB 存儲,通過 LogStorage 接口擴展自定義日志存儲實現;核心接口包括:
LogManager 負責調用底層日志存儲 LogStorage,針對日志存儲調用進行緩存、批量提交、必要的檢查和優化。
檢查Node節點,解決日志沖突。
配置管理器:緩存配置變更
LogsInMemory緩存日志Entries
Meta 存儲即元信息存儲記錄 Raft 實現的內部狀態,比如當前 term,、投票給哪個節點等信息
設置/獲取 Raft 元數據的當前任期 Term;
分配/查詢 Raft 元信息的 PeerId 節點投票。
RaftMetaStorage 元信息存儲實現,定義 Raft 元數據的 Metadata 存儲模塊核心 API 接口包括:
Snapshot 存儲用于存放用戶的狀態機 Snapshot 及元信息,用于Node重啟重建整個狀態機實例。
狀態機快照 doSnapshot(done)
安裝快照 installSnapshot(request, response, done)。
設置 filterBeforeCopyRemote ,為 true 表示復制到遠程之前過濾數據;
創建快照編寫器;
打開快照閱讀器;
從遠程 Uri 復制數據;
啟動從遠程 Uri 復制數據的復制任務;
配置 SnapshotThrottle,SnapshotThrottle 用于重盤讀/寫場景限流的,比如磁盤讀寫、網絡帶寬。
SnapshotStorage 用于 snapshot 存儲實現,定義 Raft 狀態機的 Snapshot 存儲模塊核心接口包括:
SnapshotExecutor 用于 snapshot 實際存儲、遠程安裝、復制的管理。
LogManager 調用日志存儲 LogStorage 實現邏輯:
SnapshotExecutor 狀態機快照和遠程安裝鏡像實現邏輯:
- 一致性狀態機 -
通過存儲的設計,在引入狀態機機制,就可以完成一致性狀態機。SOFAJRaft狀態機組成有:
StateMachine:業務邏輯實現的主要接口,狀態機運行在每個 raft 節點上,提交的 task 如果成功,最終都會復制應用到每個節點的狀態機上。,核心是 onApply(Iterator) 方法,應用通過 Node#apply(task) 提交的日志到業務狀態機。
FSMCaller:封裝對業務 StateMachine 的狀態轉換的調用以及日志的寫入等,一個有限狀態機的實現,做必要的檢查、請求合并提交和并發處理等。
SOFAJRaft Node節點利用日志復制完成數據同步,主要組成有:
Replicator:用于 leader 向 follower 復制日志,也就是 raft 中的 appendEntries 調用,包括心跳存活檢查等。
ReplicatorGroup: 用于單個 RAFT Group 管理所有的 replicator,必要的權限檢查和派發。
下面通過簡單介紹了下SOFAJRaft的選舉實現、存儲機制、狀態機和日志復制四個方面。基本上完成了Raft實現的核心實現。但SOFAJRaft還有更多核心及優化,因為篇幅原因沒有進入細細剖析。如果咱們自實現Raft協議,基本上也是實現這幾個主流程即可完成簡版Raft了。關于Raft協議暫時先告一段路,接下去準備開寫ZAB協議。
看完上述內容,你們對如何進行Raft協議實踐中的SOFAJRaft剖析有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。