??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來提供新的寫操作骏令。后臺線程負(fù)責(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的默認(rèn)實現(xiàn)是skiplist。除了默認(rèn)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。默認(rèn)是打開concurrent insert to memtable溯乒,也可以通過設(shè)置allow_concurrent_memtable_write來關(guān)閉豹爹。