LevelDB 完全解析(3):SSTable

前文回顧

SSTable 全稱 Sorted String Table,顧名思義,里面的 key-value 都是有序保存的患整。除了兩個(gè) MemTable砸民,LevelDB 中的大部分?jǐn)?shù)據(jù)是以 SSTable 的形式保存在外存上。

SSTable 由 compaction 生成:

  • Minor Compaction:一個(gè) MemTable 直接 dump 成 level-0 的一個(gè) SSTable浓恶。
  • Major Compaction:多個(gè) SSTable 進(jìn)行合并玫坛、重整,生成 1~多個(gè) SSTable包晰。

SSTable 的格式

SSTable 格式

在一個(gè) SSTable 中湿镀,文件末尾的 Footer 是定長(zhǎng)的,其他數(shù)據(jù)都被劃分成一個(gè)個(gè)變長(zhǎng)的 block:index block伐憾、metaindex block勉痴、meta blocks、data blocks树肃。

  • Footer
    Footer 的大小為 48 字節(jié)蒸矛,內(nèi)容是一個(gè) 8 字節(jié)的 magic number 和兩個(gè) BlockHandle —— index handle 和 meta index handle,index handle 指向 index block胸嘴,meta index handle 指向 meta index block雏掠。BlockHandle 相當(dāng)于一個(gè) block 的“指針”,由這個(gè) block 的 offset(varint64) 和 size(varint64) 組成劣像。由于采用 varint64 進(jìn)行編碼乡话,每個(gè) varint64 最多占用 10 字節(jié),所以一個(gè) BlockHandle 最多占用 20 字節(jié)驾讲。因?yàn)?BlockHandle 是定長(zhǎng)蚊伞,而 BlockHandle 編碼的結(jié)果是變長(zhǎng)的,所以 Footer 編碼的時(shí)候需要進(jìn)行 padding吮铭。

  • Index Block
    Index block 中的每條 key-value 指向一個(gè) data block时迫。value 比較簡(jiǎn)單直接,就是對(duì)應(yīng)的 data block 的 BlockHandle谓晌。key 是一個(gè)大于等于當(dāng)前 data block 中最大的 key 且小于下一個(gè) block 中最小的 key掠拳,這一塊的邏輯可以參考 FindShortestSeparator 的調(diào)用實(shí)現(xiàn)。這樣做是為了減小 index block 的體積纸肉,畢竟我們希望程序運(yùn)行的時(shí)候溺欧,index block 被盡可能 cache 在內(nèi)存中喊熟。

  • Meta Index Block
    Meta index block 中的每條 key-value 指向一個(gè) meta block。目前 LevelDB 中只有一個(gè) meta block姐刁,保存的是這個(gè) SSTable 中的 key 組成的 bloom filter芥牌。

  • Data Block
    Data block 是實(shí)際的 key-value 數(shù)據(jù)。

Block

Index block聂使、meta index block壁拉、data block 都是通過(guò) BlockBuilder 來(lái)生成,通過(guò) Block 來(lái)讀取的柏靶。最簡(jiǎn)單的方式弃理,block 里面只需要將一個(gè)個(gè) key-value 有序保存。但是為了節(jié)省空間屎蜓,LevelDB 在 block 的內(nèi)部實(shí)現(xiàn)了前綴壓縮痘昌。

前綴壓縮利用了 key 的有序性(前綴相同的有序 key 會(huì)聚集在一起)對(duì) key 進(jìn)行壓縮,每個(gè) key 與前一個(gè) key 相同的前綴部分可以不用保存炬转。讀取的時(shí)候再根據(jù)規(guī)則進(jìn)行解碼即可辆苔。

LevelDB 將 block 的一個(gè) key-value 稱為一條 entry。每條 entry 的格式如下:

entry 格式
  • shared_bytes:和前一個(gè) key 相同的前綴長(zhǎng)度返吻。
  • unshared_bytes:和前一個(gè) key不同的后綴部分的長(zhǎng)度姑子。
  • value_length:value 數(shù)據(jù)的長(zhǎng)度。
  • key_delta:和前一個(gè) key不同的后綴部分测僵。
  • value:value 數(shù)據(jù)街佑。

一個(gè) block 的數(shù)據(jù)格式如下:

block 格式
  • restarts:在 LevelDB 中,默認(rèn)每 16 個(gè) key 就會(huì)重新計(jì)算前綴壓縮捍靠,重新開(kāi)始計(jì)算前綴壓縮到第一個(gè) key 稱之為重啟點(diǎn)(restart point)沐旨。restarts 數(shù)組記錄了這個(gè) block 中所有重啟點(diǎn)的 offset。
  • num_restarts:是 restarts 數(shù)組的長(zhǎng)度榨婆。

在 block 中查找一個(gè) key(Block::Iter::Seek):

  1. 先在 restarts 數(shù)組的基礎(chǔ)上進(jìn)行二分查找磁携,確定 restart point。
  2. 從 restart point 開(kāi)始遍歷查找良风。

Filter

Meta block(bloom filter)由 FilterBlockBuilder 來(lái)生成谊迄,通過(guò) FilterBlockReader 來(lái)讀取。

后面會(huì)單獨(dú)寫一篇介紹 filter烟央。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末统诺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子疑俭,更是在濱河造成了極大的恐慌粮呢,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異啄寡,居然都是意外死亡豪硅,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門挺物,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)懒浮,“玉大人,你說(shuō)我怎么就攤上這事姻乓∏兑纾” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵蹋岩,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我学少,道長(zhǎng)剪个,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任版确,我火速辦了婚禮扣囊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绒疗。我一直安慰自己侵歇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布吓蘑。 她就那樣靜靜地躺著惕虑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪磨镶。 梳的紋絲不亂的頭發(fā)上溃蔫,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音琳猫,去河邊找鬼伟叛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛脐嫂,可吹牛的內(nèi)容都是我干的统刮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼账千,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼侥蒙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起蕊爵,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辉哥,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體醋旦,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡恒水,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了饲齐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钉凌。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖捂人,靈堂內(nèi)的尸體忽然破棺而出御雕,到底是詐尸還是另有隱情,我是刑警寧澤滥搭,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布酸纲,位于F島的核電站,受9級(jí)特大地震影響瑟匆,放射性物質(zhì)發(fā)生泄漏闽坡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一愁溜、第九天 我趴在偏房一處隱蔽的房頂上張望疾嗅。 院中可真熱鬧,春花似錦冕象、人聲如沸代承。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)论悴。三九已至,卻和暖如春席爽,著一層夾襖步出監(jiān)牢的瞬間意荤,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工只锻, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留玖像,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓齐饮,卻偏偏與公主長(zhǎng)得像捐寥,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子祖驱,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345