中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么實現Apache Bookkeeper中的Journal

發布時間:2021-12-24 10:31:52 來源:億速云 閱讀:170 作者:iii 欄目:大數據

這篇文章主要講解了“怎么實現Apache Bookkeeper中的Journal”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么實現Apache Bookkeeper中的Journal”吧!

主要功能

  1. 充當WAL

  • 寫請求處理:
    首先在Bookkeeper服務端收到了寫Entry的請求之后會交給Bookie來處理
    Bookie.addEntryInternal 這個方法會將請求攜帶的Entry信息寫入LedgerStorage(實際數據存儲的位置 + 索引)
    寫入成功之后還會同時將這個請求寫入Journal

  • 其他重要信息:比如說Ledger被fence的信息、LAC等。

  1. 啟動的時候將WAL進行replay,將記錄在journal里面的內容重新apply到LedgerStorage里面,
    避免之前寫入LedgerStorage的內容因為沒有刷盤導致丟失。

  2. checkpoint 邏輯
    和其他WAL一樣,需要記錄一個位置,這個位置標識著LedgerStorage里面的數據已經全都落盤了
    這一個位置之前的WAL日志都可以被刪除。

  3. 維護JournalChannel邏輯,寫入WAL日志,日志輪轉等。

大致邏輯

1. 寫入:

整個寫入是異步的,寫入結果通過callback進行后續處理。
寫入的參數會封裝成為一個QueueEntry放到寫請求隊列

class QueueEntry {
        // 內容
        ByteBuf entry;
        long ledgerId;
        long entryId;
        
       // 寫結果的callback
        WriteCallback cb;
       // 進入隊列的時間,用來確定是否等待時間過長
        long enqueueTime;
       // 是否需要等內容落盤
        boolean ackBeforeSync;
}

這個隊列會被一個線程定期處理,這里先叫做BookieJournalWriteThread 好了(實際沒有這個類)
取出之后會將攜帶的ByteBuffer 寫入到JournalChannel里面。這個線程專門處理這個邏輯,
其他的活不干。

這里先說下JournalChannel 這個類,這個類可以認為是底層journal磁盤文件的映射,
內部實現是一個帶讀寫緩存的FileChannel, 寫入的時候先到寫緩存,
有相應的邏輯主動觸發寫緩存寫到包裝的FileChannel里面。

QueueEntry 的字節寫入之后,可能內容在寫緩存里面。

flush 邏輯

我們需要觸發flush邏輯,將寫緩存的內容寫到FileChannel里面。

這里flush和 sync 到磁盤不是一個說法。
flush 是調用FileChannel.write 為了減少調用次數
sync 是調用FileChannel.force 為了fsync 到磁盤

這里觸發flush的條件有3種:

  1. 時間bound:這個請求入隊之后,一段時間之后必須被處理(寫入到channel或者落盤)

  2. 寫請求的個數 || 累積的寫請求的字節數

  3. 寫請求隊列為空(一般測試的時候出現這個,寫請求很少的情況下大部分都會被1這個條件兜底)

滿足flush 條件則會主動將寫緩存的內容刷到FileChannel里面。
如果不需要等待內容落盤(ackBeforeSync=false),則直接將callback提交到線程池執行回調。
之后寫請求被放到一個等待flush的batch里面。

flush邏輯做完之后,會去判斷是否需要落盤。

落盤(ForceWrite)邏輯

按照配置有下面幾種條件需要落盤。

  1. 每次flush都需要落盤。

  2. journal 文件輪轉,需要把之前的文件落盤。

  3. 按照配置的interval 落盤。

如果需要落盤則這個時候會將之前的batch 封裝成為一個ForceWriteRequest 放到落盤隊列里面。

這個隊列會被ForceWriteThread 清空。

這里可以配置一個groupCommit的邏輯。避免多次fsync
如果配置了這個則會將隊列里面的請求合并到一起,觸發單次的FileChannel.force
同樣,落盤之后會將之前的callback 放到線程池去處理回調。

2. replay 邏輯

這個邏輯比較簡單,就是啟動的時候把這個文件的內容從上次成功checkpoint的位置開始讀取。
把讀到的內容再次寫入到LedgerStorage 里面就ok。

3. checkpoint 邏輯

這個實際上和LedgerStorage 這個是聯動的,如果這一段WAL上面的內容,已經被LedgerStorage成功寫到磁盤上了,那么這段WAL就可以被刪除了。

這里會有一個LastLogMark文件,標記了(journal文件,offset)表示這個文件在這個offset之前的內容可以被干掉了。

Journal 這個類實現了CheckpointSource 這個接口。
實際動作由SyncThread (實現了Checkpointer接口)執行。

每種LedgerStorage的checkpoint觸發條件不同。

entryLogPerLedgerEnabled || isDbLedgerStorage 會按照時間interval 定期觸發checkpoint
InterleavedLedgerStorage 會在日志輪轉的時候觸發
SortedLedgerStorage 會在memtable 需要flush的時候觸發

實際邏輯比較簡單

public void checkpoint(Checkpoint checkpoint) {
       // ...
            ledgerStorage.checkpoint(checkpoint);
            checkpointSource.checkpointComplete(checkpoint, true);
       // ...
    }

checkpointComplete 這個方法會刷新磁盤上的LastLogMarker 這個文件,同時落盤。
(主要邏輯在LedgerStorage.checkpoint這里)

這里的磁盤是LedgerStorage的磁盤

寫入請求處理是異步的,提交之后就會被Journal線程處理。
Journal線程負責將內容寫入Journal channel,同時按照一定條件執行flush邏輯。
如果判斷需要進行刷盤則將刷盤batch包裝成ForceWriteRequest
ForceWriteThread清理隊列進行group commit 處理。負責journal落盤。
對于寫請求的callback不會在這兩個執行,會被額外提交到callback線程池處理。

感謝各位的閱讀,以上就是“怎么實現Apache Bookkeeper中的Journal”的內容了,經過本文的學習后,相信大家對怎么實現Apache Bookkeeper中的Journal這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

比如县| 伊宁县| 龙井市| 正蓝旗| 宾阳县| 福鼎市| 阳曲县| 疏勒县| 江口县| 横峰县| 馆陶县| 五华县| 同心县| 台前县| 芷江| 永春县| 得荣县| 巴彦县| 清新县| 夏河县| 翁牛特旗| 无锡市| 张家港市| 泗阳县| 沧州市| 青岛市| 呼和浩特市| 梅河口市| 视频| 西青区| 石泉县| 安岳县| 济阳县| 农安县| 张家川| 丹棱县| 上蔡县| 沿河| 辉县市| 准格尔旗| 靖州|