日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

蚂蚁金服生产级 Raft 算法库存储模块剖析 | SOFAJRaft 实现原理

發(fā)布時間:2024/8/23 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 蚂蚁金服生产级 Raft 算法库存储模块剖析 | SOFAJRaft 实现原理 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

SOFAJRaft?是一個基于?Raft?一致性算法的生產(chǎn)級高性能?Java?實(shí)現(xiàn),支持?MULTI-RAFT-GROUP,適用于高負(fù)載低延遲的場景

SOFAJRaft?存儲模塊分為:

  • Log?存儲記錄?Raft?配置變更和用戶提交任務(wù)日志;
  • Meta?存儲即元信息存儲記錄?Raft?實(shí)現(xiàn)的內(nèi)部狀態(tài);
  • Snapshot?存儲用于存放用戶的狀態(tài)機(jī)?Snapshot?及元信息。
  • 本文將圍繞日志存儲,元信息存儲以及快照存儲等方面剖析?SOFAJRaft?存儲模塊原理,闡述如何解決?Raft?協(xié)議存儲問題以及存儲模塊實(shí)現(xiàn):

    • Raft?配置變更和用戶提交任務(wù)日志如何存儲?如何調(diào)用管理日志存儲?
    • SOFAJRaft Server?節(jié)點(diǎn)?Node?是如何存儲?Raft?內(nèi)部配置?
    • Raft?狀態(tài)機(jī)快照?Snapshot?機(jī)制如何實(shí)現(xiàn)?如何存儲安裝鏡像?

    日志存儲

    Log?存儲,記錄?Raft?配置變更和用戶提交任務(wù)的日志,把日志從?Leader?復(fù)制到其他節(jié)點(diǎn)上面。

    • LogStorage?是日志存儲實(shí)現(xiàn),默認(rèn)實(shí)現(xiàn)基于?RocksDB?存儲,通過?LogStorage?接口擴(kuò)展自定義日志存儲實(shí)現(xiàn);
    • LogManager?負(fù)責(zé)調(diào)用底層日志存儲?LogStorage,針對日志存儲調(diào)用進(jìn)行緩存、批量提交、必要的檢查和優(yōu)化。

    LogStorage?存儲實(shí)現(xiàn)

    LogStorage?日志存儲實(shí)現(xiàn),定義?Raft?分組節(jié)點(diǎn)?Node?的?Log?存儲模塊核心?API?接口包括:

    • 返回日志里的首/末個日志索引;
    • 按照日志索引獲取?Log Entry?及其任期;
    • 把單個/批量?Log Entry?添加到日志存儲;
    • 從?Log?存儲頭部/末尾刪除日志;
    • 刪除所有現(xiàn)有日志,重置下任日志索引。

    Log Index?提交到?Raft Group?中的任務(wù)序列化為日志存儲,每條日志一個編號,在整個?Raft Group?內(nèi)單調(diào)遞增并復(fù)制到每個?Raft?節(jié)點(diǎn)。LogStorage?日志存儲實(shí)現(xiàn)接口定義入口:

    com.alipay.sofa.jraft.storage.LogStorage

    RocksDBLogStorage?基于?RocksDB?實(shí)現(xiàn)

    Log Structured Merge Tree?簡稱?LSM ,把一顆大樹拆分成?N?棵小樹,數(shù)據(jù)首先寫入內(nèi)存,內(nèi)存里構(gòu)建一顆有序小樹,隨著小樹越來越大,內(nèi)存的小樹?Flush?到磁盤,磁盤中的樹定期做合并操作合并成一棵大樹以優(yōu)化讀性能,通過把磁盤的隨機(jī)寫轉(zhuǎn)化為順序?qū)懱岣邔懶阅?#xff0c;RocksDB?就是基于?LSM-Tree?數(shù)據(jù)結(jié)構(gòu)使用?C++ 編寫的嵌入式?KV?存儲引擎,其鍵值均允許使用二進(jìn)制流。RocksDB?按順序組織所有數(shù)據(jù),通用操作包括?get(key),?put(key),?delete(Key)?以及?newIterator()。RocksDB?有三種基本的數(shù)據(jù)結(jié)構(gòu):memtable,sstfile?以及?logfile。memtable?是一種內(nèi)存數(shù)據(jù)結(jié)構(gòu)--所有寫入請求都會進(jìn)入?memtable,然后選擇性進(jìn)入?logfile。logfile?是一種有序?qū)懘鎯Y(jié)構(gòu),當(dāng)?memtable?被填滿的時候被刷到?sstfile?文件并存儲起來,然后相關(guān)的?logfile?在之后被安全地刪除。sstfile?內(nèi)的數(shù)據(jù)都是排序好的,以便于根據(jù)?key?快速搜索。

    LogStorage?默認(rèn)實(shí)現(xiàn)?RocksDBLogStorage?是基于?RocksDB?存儲日志,初始化日志存儲?StorageFactory?根據(jù)?Raft節(jié)點(diǎn)日志存儲路徑和?Raft?內(nèi)部實(shí)現(xiàn)是否調(diào)用?fsync?配置默認(rèn)創(chuàng)建?RocksDBLogStorage?日志存儲。基于?RocksDB?存儲實(shí)現(xiàn)?RocksDBLogStorage?核心操作包括:

    • init():創(chuàng)建?RocksDB?配置選項(xiàng)調(diào)用?RocksDB#open()?方法構(gòu)建?RocksDB?實(shí)例,添加?default?默認(rèn)列族及其配置選項(xiàng)獲取列族處理器,通過?newIterator()?生成?RocksDB?迭代器遍歷?KeyValue?數(shù)據(jù)檢查?Value?類型加載?Raft?配置變更到配置管理器?ConfigurationManager。RocksDB?引入列族 ColumnFamily 概念,所謂列族是指一系列 KeyValue 組成的數(shù)據(jù)集,RocksDB?讀寫操作需要指定列族,創(chuàng)建?RocksDB?默認(rèn)構(gòu)建命名為default?的列族。
    • shutdown():首先關(guān)閉列族處理器以及?RocksDB?實(shí)例,其次遍歷列族配置選項(xiàng)執(zhí)行關(guān)閉操作,接著關(guān)閉RocksDB?配置選項(xiàng),最后清除強(qiáng)引用以達(dá)到?Help GC?垃圾回收?RocksDB?實(shí)例及其配置選項(xiàng)對象。
    • getFirstLogIndex():基于處理器?defaultHandle?和讀選項(xiàng)?totalOrderReadOptions?方法構(gòu)建 RocksDB?迭代器?RocksIterator,檢查是否加載過日志里第一個日志索引,未加載需調(diào)用?seekToFirst()?方法獲取緩存 RocksDB 存儲日志數(shù)據(jù)的第一個日志索引。
    • getLastLogIndex():基于處理器?defaultHandle?和讀選項(xiàng)?totalOrderReadOptions?構(gòu)建?RocksDB?迭代器?RocksIterator,調(diào)用?seekToLast()?方法返回?RocksDB?存儲日志記錄的最后一個日志索引。
    • getEntry(index):基于處理器?defaultHandle?和指定日志索引調(diào)用?RocksDB#get()?操作返回?RocksDB?索引位置日志?LogEntry。
    • getTerm(index):基于處理器?defaultHandle?和指定日志索引調(diào)用?RocksDB#get()?操作獲取?RocksDB?索引位置日志并且返回其?LogEntry?的任期。
    • appendEntry(entry):檢查日志?LogEntry?類型是否為配置變更,配置變更類型調(diào)用?RocksDB#write()?方法執(zhí)行批量寫入,用戶提交任務(wù)的日志基于處理器?defaultHandle?和?LogEntry?對象調(diào)用?RocksDB#put()?方法存儲。
    • appendEntries(entries):調(diào)用?RocksDB#write()?方法把?Raft?配置變更或者用戶提交任務(wù)的日志同步刷盤批量寫入?RocksDB?存儲,通過?Batch Write?手段合并?IO?寫入請求減少方法調(diào)用和上下文切換。
    • truncatePrefix(firstIndexKept):獲取第一個日志索引,后臺啟動一個線程基于默認(rèn)處理器?defaultHandle?和配置處理器?confHandle?執(zhí)行?RocksDB#deleteRange()?操作刪除從?Log?頭部以第一個日志索引到指定索引位置范圍的?RocksDB?日志數(shù)據(jù)。
    • truncateSuffix(lastIndexKept):獲取最后一個日志索引,基于默認(rèn)處理器?defaultHandle?和配置處理器?confHandle?執(zhí)行?RocksDB#deleteRange()?操作清理從?Log?末尾以指定索引位置到最后一個索引范疇的?RocksDB?未提交日志。
    • reset(nextLogIndex):獲取?nextLogIndex?索引對應(yīng)的?LogEntry,執(zhí)行?RocksDB#close()?方法關(guān)閉?RocksDB實(shí)例,調(diào)用?RocksDB#destroyDB()?操作銷毀?RocksDB?實(shí)例清理?RocksDB?所有數(shù)據(jù),重新初始化加載?RocksDB?實(shí)例并且重置下一個日志索引位置。

    RocksDBLogStorage?基于?RocksDB?存儲日志實(shí)現(xiàn)核心入口:

    com.alipay.sofa.jraft.storage.RocksDBLogStorage

    LogManager?存儲調(diào)用

    日志管理器?LogManager?負(fù)責(zé)調(diào)用?Log?日志存儲?LogStorage,對?LogStorage?調(diào)用進(jìn)行緩存管理、批量提交、檢查優(yōu)化。Raft?分組節(jié)點(diǎn)?Node?初始化/啟動時初始化日志存儲?StorageFactory?構(gòu)建日志管理器?LogManager,基于日志存儲?LogStorage、配置管理器?ConfigurationManager、有限狀態(tài)機(jī)調(diào)用者?FSMCaller、節(jié)點(diǎn)性能監(jiān)控?NodeMetrics?等?LogManagerOptions?配置選項(xiàng)實(shí)例化?LogManager。根據(jù)?Raft?節(jié)點(diǎn)?Disruptor Buffer?大小配置生成穩(wěn)定狀態(tài)回調(diào)?StableClosure?事件?Disruptor?隊(duì)列,設(shè)置穩(wěn)定狀態(tài)回調(diào)?StableClosure?事件處理器?StableClosureEventHandler?處理隊(duì)列事件,其中?StableClosureEventHandler?處理器事件觸發(fā)的時候判斷任務(wù)回調(diào)?StableClosure?的?Log Entries?是否為空,如果任務(wù)回調(diào)的?Log Entries?為非空需積攢日志條目批量?Flush,空則檢查?StableClosureEvent?事件類型并且調(diào)用底層存儲?LogStorage#appendEntries(entries)?批量提交日志寫入?RocksDB,當(dāng)事件類型為SHUTDOWN、RESET、TRUNCATE_PREFIX、TRUNCATE_SUFFIX、LAST_LOG_ID?時調(diào)用底層日志存儲?LogStorage?進(jìn)行指定事件回調(diào)?ResetClosure、TruncatePrefixClosure、TruncateSuffixClosure、LastLogIdClosure?處理。

    當(dāng)?Client?向?SOFAJRaft?發(fā)送命令之后,Raft?分組節(jié)點(diǎn)?Node?的日志管理器?LogManager?首先將命令以 Log 的形式存儲到本地,調(diào)用?appendEntries(entries,?done)?方法檢查?Node?節(jié)點(diǎn)當(dāng)前為?Leader?并且?Entries?來源于用戶未知分配到的正確日志索引時需要分配索引給添加的日志?Entries?,而當(dāng)前為?Follower?時并且?Entries?來源于?Leader?必須檢查以及解決本地日志和??Entries?之間的沖突。接著遍歷日志條目?Log Entries?檢查類型是否為配置變更,配置管理器?ConfigurationManager?緩存配置變更?Entry,將現(xiàn)有日志條目?Entries?添加到?logsInMemory?進(jìn)行緩存,穩(wěn)定狀態(tài)回調(diào)?StableClosure?設(shè)置需要存儲的日志,發(fā)布?OTHER?類型事件到穩(wěn)定狀態(tài)回調(diào)?StableClosure?事件隊(duì)列,觸發(fā)穩(wěn)定狀態(tài)回調(diào)?StableClosure?事件處理器?StableClosureEventHandler?處理該事件,處理器獲取任務(wù)回調(diào)的?Log Entries?把日志條目積累到內(nèi)存中以便后續(xù)統(tǒng)一批量?Flush,通過?appendToStorage(toAppend)?操作調(diào)用底層LogStorage?存儲日志?Entries。同時?Replicator?把此條?Log?復(fù)制給其他的?Node?實(shí)現(xiàn)并發(fā)的日志復(fù)制,當(dāng)?Node?接收集群中半數(shù)以上的?Node?返回的“復(fù)制成功”的響應(yīng)將這條?Log?以及之前的?Log?有序的發(fā)送至狀態(tài)機(jī)里面執(zhí)行。

    LogManager?調(diào)用日志存儲?LogStorage?實(shí)現(xiàn)邏輯:

    元信息存儲

    Metadata?存儲即元信息存儲,用來存儲記錄?Raft?實(shí)現(xiàn)的內(nèi)部狀態(tài),譬如當(dāng)前任期?Term、投票給哪個?PeerId?節(jié)點(diǎn)等信息。

    RaftMetaStorage?存儲實(shí)現(xiàn)

    RaftMetaStorage?元信息存儲實(shí)現(xiàn),定義?Raft?元數(shù)據(jù)的?Metadata?存儲模塊核心?API?接口包括:

    • 設(shè)置/獲取?Raft?元數(shù)據(jù)的當(dāng)前任期?Term;
    • 分配/查詢?Raft?元信息的?PeerId?節(jié)點(diǎn)投票。

    Raft?內(nèi)部狀態(tài)任期?Term?是在整個?Raft Group?里單調(diào)遞增的?long?數(shù)字,用來表示一輪投票的編號,其中成功選舉出來的?Leader?對應(yīng)的?Term?稱為?Leader Term,Leader?沒有發(fā)生變更期間提交的日志都有相同的?Term?編號。PeerId?表示?Raft?協(xié)議的參與者(Leader/Follower/Candidate?etc.), 由三元素組成:?ip:port:index,其中?ip?是節(jié)點(diǎn)的?IP,?port?是端口,?index?表示同一個端口的序列號。RaftMetaStorage?元信息存儲實(shí)現(xiàn)接口定義入口:

    com.alipay.sofa.jraft.storage.RaftMetaStorage

    LocalRaftMetaStorage?基于?ProtoBuf?實(shí)現(xiàn)

    Protocol Buffers?是一種輕便高效的結(jié)構(gòu)化數(shù)據(jù)存儲格式,用于結(jié)構(gòu)化數(shù)據(jù)串行化或者說序列化,適合做數(shù)據(jù)存儲或?RPC?數(shù)據(jù)交換格式,用于通訊協(xié)議、數(shù)據(jù)存儲等領(lǐng)域的語言無關(guān)、平臺無關(guān)、可擴(kuò)展的序列化結(jié)構(gòu)數(shù)據(jù)格式。用戶在?.proto?文件定義?Protocol Buffer?的?Message?類型指定需要序列化的數(shù)據(jù)結(jié)構(gòu),每一個?Message??都是一個小的信息邏輯單元包含一系列的鍵值對,每種類型的?Message?涵蓋一個或者多個唯一編碼字段,每個字段由名稱和值類型組成,允許?Message?定義可選字段?Optional Fields、必須字段?Required Fields、可重復(fù)字段?Repeated Fields。

    RaftMetaStorage?默認(rèn)實(shí)現(xiàn)?LocalRaftMetaStorage?是基于?ProtoBuf??Message?本地存儲?Raft?元數(shù)據(jù),初始化元信息存儲?StorageFactory?根據(jù)?Raft?元信息存儲路徑、?Raft?內(nèi)部配置以及?Node?節(jié)點(diǎn)監(jiān)控默認(rèn)創(chuàng)建?LocalRaftMetaStorage?元信息存儲。基于?ProtoBuf?存儲實(shí)現(xiàn)?LocalRaftMetaStorage?主要操作包括:

    • init():獲取?Raft?元信息存儲配置?RaftMetaStorageOptions?節(jié)點(diǎn)?Node,讀取命名為?raft_meta?的?ProtoBufFile?文件加載?StablePBMeta?消息,根據(jù)?StablePBMeta?ProtoBuf?元數(shù)據(jù)緩存?Raft?當(dāng)前任期?Term?和?PeerId?節(jié)點(diǎn)投票信息。
    • shutdown():獲取內(nèi)存里?Raft?當(dāng)前任期?Term?和?PeerId?節(jié)點(diǎn)投票構(gòu)建?StablePBMeta?消息,按照?Raft?內(nèi)部是否同步元數(shù)據(jù)配置寫入?ProtoBufFile?文件。
    • setTerm(term):檢查?LocalRaftMetaStorage?初始化狀態(tài),緩存設(shè)置的當(dāng)前任期?Term,按照?Raft?是否同步元數(shù)據(jù)配置把當(dāng)前任期?Term?作為?ProtoBuf?消息保存到?ProtoBufFile?文件。
    • getTerm():檢查?LocalRaftMetaStorage?初始化狀態(tài),返回緩存的當(dāng)前任期?Term。
    • setVotedFor(peerId):檢查?LocalRaftMetaStorage?初始化狀態(tài),緩存投票的?PeerId?節(jié)點(diǎn),按照?Raft?是否同步元數(shù)據(jù)配置把投票?PeerId?節(jié)點(diǎn)作為?ProtoBuf?消息保存到?ProtoBufFile?文件。
    • getVotedFor():檢查?LocalRaftMetaStorage?初始化狀態(tài),返回緩存的投票?PeerId?節(jié)點(diǎn)。

    LocalRaftMetaStorage?基于?ProtoBuf?本地存儲?Raft?元信息實(shí)現(xiàn)入口:

    com.alipay.sofa.jraft.storage.impl.LocalRaftMetaStorage

    快照存儲

    當(dāng)?Raft?節(jié)點(diǎn)?Node?重啟時,內(nèi)存中狀態(tài)機(jī)的狀態(tài)數(shù)據(jù)丟失,觸發(fā)啟動過程重新存放日志存儲?LogStorage?的所有日志重建整個狀態(tài)機(jī)實(shí)例,此種場景會導(dǎo)致兩個問題:

    • 如果任務(wù)提交比較頻繁,例如消息中間件場景導(dǎo)致整個重建過程很長啟動緩慢;
    • 如果日志非常多并且節(jié)點(diǎn)需要存儲所有的日志,對存儲來說是資源占用不可持續(xù);
    • 如果增加?Node?節(jié)點(diǎn),新節(jié)點(diǎn)需要從?Leader?獲取所有的日志重新存放至狀態(tài)機(jī),對于?Leader?和網(wǎng)絡(luò)帶寬都是不小的負(fù)擔(dān)。?


    因此通過引入?Snapshot?機(jī)制來解決此三個問題,所謂快照?Snapshot?即對數(shù)據(jù)當(dāng)前值的記錄,是為當(dāng)前狀態(tài)機(jī)的最新狀態(tài)構(gòu)建"鏡像"單獨(dú)保存,保存成功刪除此時刻之前的日志減少日志存儲占用;啟動的時候直接加載最新的?Snapshot?鏡像,然后重放在此之后的日志即可,如果?Snapshot?間隔合理,整個重放到狀態(tài)機(jī)過程較快,加速啟動過程。最后新節(jié)點(diǎn)的加入先從?Leader?拷貝最新的?Snapshot?安裝到本地狀態(tài)機(jī),然后只要拷貝后續(xù)的日志即可,能夠快速跟上整個?Raft Group?的進(jìn)度。Leader?生成快照有幾個作用:

    • 當(dāng)有新的節(jié)點(diǎn)?Node?加入集群不用只靠日志復(fù)制、回放機(jī)制和?Leader?保持?jǐn)?shù)據(jù)一致,通過安裝?Leader?的快照方式跳過早期大量日志的回放;
    • Leader?用快照替代?Log?復(fù)制減少網(wǎng)絡(luò)端的數(shù)據(jù)量;
    • 用快照替代早期的?Log?節(jié)省存儲占用空間。

    Snapshot?存儲,用于存儲用戶的狀態(tài)機(jī)?Snapshot?及元信息:

    • SnapshotStorage?用于?Snapshot?存儲實(shí)現(xiàn);
    • SnapshotExecutor?用于管理?Snapshot?存儲、遠(yuǎn)程安裝、復(fù)制。

    SnapshotStorage?存儲實(shí)現(xiàn)

    SnapshotStorage?快照存儲實(shí)現(xiàn),定義?Raft?狀態(tài)機(jī)的?Snapshot?存儲模塊核心?API?接口包括:

    • 設(shè)置?filterBeforeCopyRemote?設(shè)置為?true?復(fù)制到遠(yuǎn)程之前過濾數(shù)據(jù);
    • 創(chuàng)建快照編寫器;
    • 打開快照閱讀器;
    • 從遠(yuǎn)程?Uri?復(fù)制數(shù)據(jù);
    • 啟動從遠(yuǎn)程?Uri?復(fù)制數(shù)據(jù)的復(fù)制任務(wù);
    • 配置?SnapshotThrottle,SnapshotThrottle?用于重盤讀/寫場景限流的,比如磁盤讀寫、網(wǎng)絡(luò)帶寬。

    LocalSnapshotStorage?基于本地文件實(shí)現(xiàn)

    SnapshotStorage?默認(rèn)實(shí)現(xiàn)?LocalSnapshotStorage?是基于本地文件存儲?Raft?狀態(tài)機(jī)鏡像,初始化元快照存儲?StorageFactory?根據(jù)?Raft?鏡像快照存儲路徑和?Raft?配置信息默認(rèn)創(chuàng)建?LocalSnapshotStorage?快照存儲。基于本地文件存儲實(shí)現(xiàn)?LocalSnapshotStorage?主要方法包括:

    • init():刪除文件命名為?temp?的臨時鏡像?Snapshot,銷毀文件前綴為?snapshot_ 的舊快照?Snapshot,獲取快照最后一個索引?lastSnapshotIndex。
    • close():按照快照最后一個索引?lastSnapshotIndex?和鏡像編寫器?LocalSnapshotWriter?快照索引重命名臨時鏡像?Snapshot?文件,銷毀編寫器?LocalSnapshotWriter?存儲路徑快照。
    • create():銷毀文件命名為?temp?的臨時快照?Snapshot,基于臨時鏡像存儲路徑創(chuàng)建初始化快照編寫器?LocalSnapshotWriter,加載文件命名為?__raft_snapshot_meta?的?Raft?快照元數(shù)據(jù)至內(nèi)存。
    • open():根據(jù)快照最后一個索引?lastSnapshotIndex?獲取文件前綴為?snapshot_ 快照存儲路徑,基于快照存儲路徑創(chuàng)建初始化快照閱讀器?LocalSnapshotReader,加載文件命名為?__raft_snapshot_meta?的?Raft?鏡像元數(shù)據(jù)至內(nèi)存。
    • startToCopyFrom(uri,?opts):創(chuàng)建初始化狀態(tài)機(jī)快照復(fù)制器?LocalSnapshotCopier,生成遠(yuǎn)程文件復(fù)制器?RemoteFileCopier,基于遠(yuǎn)程服務(wù)地址?Endpoint?獲取?Raft?客戶端?RPC?服務(wù)連接指定?Uri,啟動后臺線程復(fù)制?Snapshot?鏡像數(shù)據(jù),加載?Raft?快照元數(shù)據(jù)獲取遠(yuǎn)程快照?Snapshot?鏡像文件,讀取遠(yuǎn)程指定快照存儲路徑數(shù)據(jù)拷貝到?BoltSession,快照復(fù)制器?LocalSnapshotCopier?同步?Raft?快照元數(shù)據(jù)。

    SnapshotExecutor?存儲管理

    快照執(zhí)行器?SnapshotExecutor?負(fù)責(zé)?Raft?狀態(tài)機(jī)?Snapshot?存儲、Leader?遠(yuǎn)程安裝快照、復(fù)制鏡像?Snapshot?文件,包括兩大核心操作:狀態(tài)機(jī)快照?doSnapshot(done) 和安裝快照?installSnapshot(request, response, done)。StateMachine?快照?doSnapshot(done)?獲取基于臨時鏡像?temp?文件路徑的?Snapshot?存儲快照編寫器?LocalSnapshotWriter,加載?__raft_snapshot_meta?快照元數(shù)據(jù)文件初始化編寫器;構(gòu)建保存鏡像回調(diào)SaveSnapshotDone?提供?FSMCaller?調(diào)用?StateMachine?的狀態(tài)轉(zhuǎn)換發(fā)布?SNAPSHOT_SAVE?類型任務(wù)事件到?Disruptor?隊(duì)列,通過?Ring Buffer?方式觸發(fā)申請任務(wù)處理器?ApplyTaskHandler?運(yùn)行快照保存任務(wù),調(diào)用?onSnapshotSave()?方法存儲各種類型狀態(tài)機(jī)快照。遠(yuǎn)程安裝快照?installSnapshot(request, response, done)?按照安裝鏡像請求響應(yīng)以及快照原信息創(chuàng)建并且注冊快照下載作業(yè)?DownloadingSnapshot,加載快照下載?DownloadingSnapshot?獲取當(dāng)前快照拷貝器的閱讀器?SnapshotReader,構(gòu)建安裝鏡像回調(diào)?InstallSnapshotDone 分配?FSMCaller?調(diào)用?StateMachine?的狀態(tài)轉(zhuǎn)換發(fā)布?SNAPSHOT_LOAD?類型任務(wù)事件到?Disruptor?隊(duì)列,也是通過?Ring Buffer?觸發(fā)申請任務(wù)處理器?ApplyTaskHandler?執(zhí)行快照安裝任務(wù),調(diào)用?onSnapshotLoad()?操作加載各種類型狀態(tài)機(jī)快照。

    SnapshotExecutor?狀態(tài)機(jī)快照和遠(yuǎn)程安裝鏡像實(shí)現(xiàn)邏輯:

    總結(jié)

    本文從?Log?日志存儲?LogStorage、Meta?元信息存儲?RaftMetaStorage?以及?Snapshot?快照存儲?SnapshotStorage?三個方面詳述?SOFAJRaft?存儲模塊實(shí)現(xiàn)細(xì)節(jié),直觀刻畫?SOFAJRaft Server?節(jié)點(diǎn)?Node?之間存儲日志、Raft?配置和鏡像流程。


    原文鏈接
    本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。

    總結(jié)

    以上是生活随笔為你收集整理的蚂蚁金服生产级 Raft 算法库存储模块剖析 | SOFAJRaft 实现原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。