RocksDB系列五:MemTable

??MemTable是一種在內(nèi)存中保存數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu),然后再在合適的時機,MemTable中的數(shù)據(jù)會flush到SST file中。MemTable既可以支持讀服務(wù)也可以支持寫服務(wù),寫操作會首先將數(shù)據(jù)寫入Memtable,讀操作在query SST files之前會首先從MemTable中query數(shù)據(jù)(因為MemTable中的數(shù)據(jù)一直是最新的)。一旦MemTable滿了,就會轉(zhuǎn)換為只讀的不可改變的,然后會創(chuàng)建一個新的MemTable來提供新的寫操作。后臺線程負責(zé)將MemTable中的數(shù)據(jù)flush到SST file,然后這個MemTable就會被銷毀。
??重要的配置

  • memtable_factory:memtable的工廠對象。通過這個工廠對象,用戶可以改變memtable的底層實現(xiàn)并提供個性化的實現(xiàn)配置。
  • write_buff_size :單個內(nèi)存表的大小限制
  • db_write_buff_size: 所有列族的內(nèi)存表總大小。這個配置可以管理內(nèi)存表的總內(nèi)存占用。
  • write_buffer_manager : 這個配置不是管理所有memtable的總內(nèi)存占用,而是,提供用戶自定義的write buffer manager來管理整體的內(nèi)存表內(nèi)存使用。這個配置會覆蓋db_write_buffer_size。
  • max_write_buffer_number:內(nèi)存表的最大個數(shù)

??memtable的默認實現(xiàn)是skiplist。除了默認memtable實現(xiàn)外,用戶也可以使用其他類型的實現(xiàn)方法比如 HashLinkList、HashSkipList or Vector 來提高查詢性能。

Skiplist MemTable

??基于Skiplist的memtable在支持讀、寫、隨機訪問和順序scan時提供了較好的性能。此外,還支持了一些其他實現(xiàn)不能支持的feature比如concurrent insert和 insert with hint。

HashSkiplist MemTable

??如其名,HashSkipList是在hash table中組織數(shù)據(jù),hash table中的每個bucket都是一個skip list,HashLinkList也是在hash table中組織數(shù)據(jù),但是每一個bucket是一個有序的單鏈表。這兩種結(jié)構(gòu)實現(xiàn)目的都是在執(zhí)行query操作時可以減少比較次數(shù)。一種使用場景就是把這種memtable和PlainTable SST格式結(jié)合在一起,然后將數(shù)據(jù)保存在RAMFS中。
??當(dāng)執(zhí)行檢索或者插入一個key時,key的前綴可以通過Options.prefix_extractor來檢索,之后就找到了相應(yīng)的hash bucket。進入到 hash bucket內(nèi)部后,使用全部的key數(shù)據(jù)來進行比較操作。使用hash實現(xiàn)的memtable的最大限制是:當(dāng)在多個key前綴上執(zhí)行scan操作需要執(zhí)行copy和sort操作,非常慢且很耗內(nèi)存。

flush

在以下三種情況下,內(nèi)存表的flush操作會被觸發(fā):

  • 內(nèi)存表大小超過了write_buffer_size
  • 全部列族的所有內(nèi)存表大小超過了db_write_buffer_size,或者wrtie_buffer_manager發(fā)出了flush的指令。這種情況下,最大的內(nèi)存表會被選擇進行flush操作。
  • 全部的WAL文件大小超過max_total_wal_size。在這種場景下,內(nèi)存中數(shù)據(jù)最老的內(nèi)存表會被選擇執(zhí)行flush操作,然后這個內(nèi)存表對應(yīng)的WAL file會被回收。

所以,內(nèi)存表也可以在未滿時執(zhí)行flush操作。這也是產(chǎn)生的SST file比對應(yīng)的內(nèi)存表小的一個原因,壓縮是是另一個原因(內(nèi)存表總的數(shù)據(jù)是沒有壓縮的,SST file是壓縮過的)。

Concurrent Insert

如果不支持concurrent insert to memtable的話,來自多個線程的concurrent 寫會順序地寫入memtable。默認是打開concurrent insert to memtable,也可以通過設(shè)置allow_concurrent_memtable_write來關(guān)閉。

Comparison

F7AC6702-7706-4f33-84BA-4ECC4047F567.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 第一章 Nginx簡介 Nginx是什么 沒有聽過Nginx?那么一定聽過它的“同行”Apache吧!Ngi...
    JokerW閱讀 33,035評論 24 1,002
  • 最近項目中用到這個nb的玩意,所以就花時間研究了下,同時整理下助自己記憶。這個猛虎上山的logo就是rocksdb...
    小東_16d3閱讀 9,541評論 3 10
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 32,315評論 2 89
  • 有一瞬間,你忽然覺得自己愛上一個人。 像是獨自在黢黑無際的長夜漫無目的的走了很久,早已如常的踽踽涼涼里忽然迸出一絲...
    _占位符_閱讀 680評論 0 0
  • 第一次用毛筆畫水彩,筆不太好控制,調(diào)顏色是一個很神奇的過程。 多一點顏料,瓶子就變成了青花瓷,果子就到了最新鮮的時...
    Jessie年糕閱讀 449評論 2 0

友情鏈接更多精彩內(nèi)容