博客專(zhuān)欄

EEPW首頁(yè) > 博客 > RocksDB 二級(jí)緩存

RocksDB 二級(jí)緩存

發(fā)布人:天翼云開(kāi)發(fā)者 時(shí)間:2024-08-02 來(lái)源:工程師 發(fā)布文章

本文分享自天翼云開(kāi)發(fā)者社區(qū)《RocksDB 二級(jí)緩存》,作者:b****n

RocksDB 團(tuán)隊(duì)正在實(shí)現(xiàn)對(duì)非易失性介質(zhì)上的塊緩存的支持??梢钥醋魇?RocksDB 當(dāng)前的易失性塊緩存的擴(kuò)展。非易失性塊緩存充當(dāng)?shù)诙泳彺妫渲邪瑥囊资跃彺嬷兄鸪龅膲K。當(dāng)這些塊由于訪問(wèn)而變得更熱時(shí),它們會(huì)被提升到易失性緩存中。

此功能適用于數(shù)據(jù)庫(kù)位于遠(yuǎn)程存儲(chǔ)或云存儲(chǔ)上的情況。非易失性緩存在 RocksDB 中被稱(chēng)為 SecondaryCache。通過(guò)維護(hù)比 DRAM 大一個(gè)數(shù)量級(jí)的二級(jí)緩存,需要從遠(yuǎn)程存儲(chǔ)讀取的次數(shù)會(huì)更少,從而減少讀取延遲和網(wǎng)絡(luò)帶寬消耗。

從用戶的角度來(lái)看,本地閃存緩存將支持以下需求:

1.打開(kāi)數(shù)據(jù)庫(kù)時(shí)提供指向二級(jí)緩存的指針。

2.能夠在同一進(jìn)程中跨DB共享二級(jí)緩存。

3.一臺(tái)主機(jī)上有多個(gè)二級(jí)緩存。

4.通過(guò)確保緩存鍵的可重復(fù)性,支持跨進(jìn)程重啟和重啟持久化緩存。

設(shè)計(jì)

在為 SecondaryCache 設(shè)計(jì) API 時(shí),我們可以選擇使其對(duì) RocksDB 代碼可見(jiàn)或?qū)⑵潆[藏在 RocksDB 塊緩存后面。將它隱藏在塊緩存后面有幾個(gè)優(yōu)點(diǎn):

1.允許靈活地將塊插入二級(jí)緩存。塊可以在從 RAM 層逐出時(shí)插入,也可以立即插入。

2.無(wú)論是否配置了二級(jí)緩存,它通過(guò)提供統(tǒng)一的接口來(lái)降低 RocksDB 代碼的其余部分的復(fù)雜性。

3.使并行讀取、在緩存中查看預(yù)取、故障處理等更容易。

4.如果需要,可以更輕松地?cái)U(kuò)展為壓縮數(shù)據(jù),并允許將其他持久性媒體添加為附加層。

我們決定通過(guò)將二級(jí)緩存隱藏在block cache后面,使二級(jí)緩存對(duì)其余 RocksDB 代碼透明。我們需要解決的一個(gè)關(guān)鍵問(wèn)題是緩存項(xiàng)的內(nèi)存分配和所有權(quán),插入二級(jí)緩存可能需要由其分配內(nèi)存。這意味著需要將緩存對(duì)象中可以轉(zhuǎn)移到二級(jí)緩存的部分復(fù)制出來(lái),并且在查找時(shí)需要將二級(jí)緩存中存儲(chǔ)的數(shù)據(jù)提供給對(duì)象構(gòu)造函數(shù)。對(duì)于 RocksDB 緩存對(duì)象,如數(shù)據(jù)塊、索引和過(guò)濾器塊以及壓縮字典,解包涉及復(fù)制出塊的原始未壓縮塊,打包涉及使用原始未壓縮數(shù)據(jù)構(gòu)造相應(yīng)的塊/索引/過(guò)濾器/字典對(duì)象。

我們考慮的另一種選擇是現(xiàn)有的 PersistentCache 接口。但是,我們決定不追求它并最終棄用它,原因如下:

1.它直接暴露給表讀取器代碼,這使得實(shí)現(xiàn)不同策略將其擴(kuò)展到更復(fù)雜的準(zhǔn)入控制策略變得更加困難。

2.該接口不允許自定義內(nèi)存分配和對(duì)象打包/解包,因此無(wú)論如何都必須定義新的 API。

3.當(dāng)前的 PersistentCache 實(shí)現(xiàn)非常簡(jiǎn)單,沒(méi)有任何準(zhǔn)入控制策略。

應(yīng)用程序接口

RocksDB 的塊緩存和二級(jí)緩存之間的接口被設(shè)計(jì)為允許可插拔實(shí)現(xiàn)。對(duì)于企業(yè)內(nèi)部使用,我們計(jì)劃使用帶有wrapper的Cachelib提供插件實(shí)現(xiàn),并使用folly等f(wàn)bcode庫(kù),RocksDB無(wú)法直接使用,來(lái)高效實(shí)現(xiàn)緩存操作。下圖顯示了塊的插入和查找流程:

二級(jí)緩存中的項(xiàng)目由 SecondaryCacheHandle 引用。句柄可能不會(huì)立即準(zhǔn)備好或具有有效值。調(diào)用者可以調(diào)用 IsReady() 以確定它是否準(zhǔn)備就緒,并且可以調(diào)用 Wait() 以阻塞直到它準(zhǔn)備就緒。調(diào)用方必須在準(zhǔn)備就緒后調(diào)用 Value() 以確定項(xiàng)目是否已成功讀取。Value() 必須在失敗時(shí)返回 nullptr。

二級(jí)緩存的用戶(例如,通過(guò) LRUCache 間接調(diào)用的 BlockBasedTableReader)必須實(shí)現(xiàn) CacheItemHelper 中定義的回調(diào),以便于解包/打包對(duì)象以保存到二級(jí)緩存和從中恢復(fù)。必須實(shí)現(xiàn) CreateCallback 以從二級(jí)緩存中的原始數(shù)據(jù)構(gòu)造可緩存對(duì)象。

二級(jí)緩存提供者必須提供 SecondaryCache 抽象類(lèi)的具體實(shí)現(xiàn)。

SecondaryCache 由用戶通過(guò)在 LRUCacheOptions 中提供指向它的指針來(lái)配置。

當(dāng)前進(jìn)展

最初的 RocksDB 對(duì)二級(jí)緩存的支持已經(jīng)合并到主分支中,并將在 6.21 版本中提供。這包括在實(shí)例化 RocksDB 的 LRU 緩存(易失性塊緩存)時(shí)為用戶提供一種配置二級(jí)緩存的方法,將從 LRU 緩存驅(qū)逐的塊溢出到閃存緩存,將塊從 SecondaryCache 讀取到 LRU 緩存,更新工具例如 cache_bench 和 db_bench 來(lái)指定閃存緩存。相關(guān)的 PR 是#8271、#8191#8312

我們使用上述 PR 以及基于 Cachelib 的 SecondaryCache 實(shí)現(xiàn)制作了端到端解決方案的原型。我們運(yùn)行了一個(gè) mixgraph 基準(zhǔn)測(cè)試來(lái)模擬真實(shí)的讀/寫(xiě)工作負(fù)載。結(jié)果顯示,與沒(méi)有本地緩存相比,使用本地閃存緩存可提高 15%,網(wǎng)絡(luò)讀取減少約 25-30%,緩存未命中率相應(yīng)減少。

未來(lái)展望

在短期內(nèi),我們計(jì)劃執(zhí)行以下操作以將 SecondaryCache 與 RocksDB 完全集成:

1.使用DB session ID作為緩存鍵前綴,保證唯一性和可重復(fù)性

2.優(yōu)化 MultiGet 和迭代器工作負(fù)載的閃存緩存使用

3.壓力測(cè)試

4.更多基準(zhǔn)測(cè)試

從長(zhǎng)遠(yuǎn)來(lái)看,我們計(jì)劃將其部署在 Facebook 的生產(chǎn)環(huán)境中。

*博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



關(guān)鍵詞: RocksDB 緩存 云計(jì)算

相關(guān)推薦

技術(shù)專(zhuān)區(qū)

關(guān)閉