LSM compaction 流程

原本想寫一下怎麼把compaction和AI結合起來,先轉個compaction的簡要過程吧。git

參考資料:
https://github.com/abbshr/abb...
https://maiyang.me/post/2017-...
http://leonlibraries.github.i...github

對於LevelDb來講,寫入記錄操做很簡單,刪除記錄僅僅寫入一個刪除標記就算完事了,可是讀取記錄比較複雜,須要在內存以及各個層級文件中依照新鮮程度依次查找,代價很高。爲了加快讀取速度,levelDb採起了compaction的方式來對已有的記錄進行整理壓縮,經過這種方式,來刪除掉一些再也不有效的KV數據,減少數據規模,減小文件數量等。post

levelDb的compaction機制和過程與Bigtable所講述的是基本一致的,Bigtable中講到三種類型的compaction: minor ,major和full。所謂minor Compaction,就是把memtable中的數據導出到SSTable文件中;major compaction就是合併不一樣層級的SSTable文件,而full compaction就是將全部SSTable進行合併。

 LevelDb包含其中兩種,minor和major。

朗格科技將爲你們詳細敘述其機理。

先來看看minor Compaction的過程。Minor compaction 的目的是當內存中的memtable大小到了必定值時,將內容保存到磁盤文件中,圖8.1是其機理示意圖。


 從8.1能夠看出,當memtable數量到了必定程度會轉換爲immutable memtable,此時不能往其中寫入記錄,只能從中讀取KV內容。以前介紹過,immutable memtable實際上是一個多層級隊列SkipList,其中的記錄是根據key有序排列的。因此這個minor compaction實現起來也很簡單,就是按照immutable memtable中記錄由小到大遍歷,並依次寫入一個level 0 的新建SSTable文件中,寫完後創建文件的index 數據,這樣就完成了一次minor compaction。從圖中也能夠看出,對於被刪除的記錄,在minor compaction過程當中並不真正刪除這個記錄,緣由也很簡單,這裏只知道要刪掉key記錄,可是這個KV數據在哪裏?那須要複雜的查找,因此在minor compaction的時候並不作刪除,只是將這個key做爲一個記錄寫入文件中,至於真正的刪除操做,在之後更高層級的compaction中會去作。

 當某個level下的SSTable文件數目超過必定設置值後,levelDb會從這個level的SSTable中選擇一個文件(level>0),將其和高一層級的level+1的SSTable文件合併,這就是major compaction。

咱們知道在大於0的層級中,每一個SSTable文件內的Key都是由小到大有序存儲的,並且不一樣文件之間的key範圍(文件內最小key和最大key之間)不會有任何重疊。Level 0的SSTable文件有些特殊,儘管每一個文件也是根據Key由小到大排列,可是由於level 0的文件是經過minor compaction直接生成的,因此任意兩個level 0下的兩個sstable文件可能再key範圍上有重疊。因此在作major compaction的時候,對於大於level 0的層級,選擇其中一個文件就行,可是對於level 0來講,指定某個文件後,本level中極可能有其餘SSTable文件的key範圍和這個文件有重疊,這種狀況下,要找出全部有重疊的文件和level 1的文件進行合併,即level 0在進行文件選擇的時候,可能會有多個文件參與major compaction。

levelDb在選定某個level進行compaction後,還要選擇是具體哪一個文件要進行compaction,levelDb在這裏有個小技巧,就是說輪流來,好比此次是文件A進行compaction,那麼下次就是在key range上緊挨着文件A的文件B進行compaction,這樣每一個文件都會有機會輪流和高層的level 文件進行合併。code

若是選好了level L的文件A和level L+1層的文件進行合併,那麼問題又來了,應該選擇level L+1哪些文件進行合併?levelDb選擇L+1層中和文件A在key range上有重疊的全部文件來和文件A進行合併。排序

也就是說,選定了level L的文件A,以後在level L+1中找到了全部須要合併的文件B,C,D…..等等。剩下的問題就是具體是如何進行major 合併的?就是說給定了一系列文件,每一個文件內部是key有序的,如何對這些文件進行合併,使得新生成的文件仍然Key有序,同時拋掉哪些再也不有價值的KV數據。

 Major compaction的過程以下:對多個文件採用多路歸併排序的方式,依次找出其中最小的Key記錄,也就是對多個文件中的全部記錄從新進行排序。以後採起必定的標準判斷這個Key是否還須要保存,若是判斷沒有保存價值,那麼直接拋掉,若是以爲還須要繼續保存,那麼就將其寫入level L+1層中新生成的一個SSTable文件中。就這樣對KV數據一一處理,造成了一系列新的L+1層數據文件,以前的L層文件和L+1層參與compaction 的文件數據此時已經沒有意義了,因此所有刪除。這樣就完成了L層和L+1層文件記錄的合併過程。

那麼在major compaction過程當中,判斷一個KV記錄是否拋棄的標準是什麼呢?其中一個標準是:對於某個key來講,若是在小於L層中存在這個Key,那麼這個KV在major compaction過程當中能夠拋掉。由於咱們前面分析過,對於層級低於L的文件中若是存在同一Key的記錄,那麼說明對於Key來講,有更新鮮的Value存在,那麼過去的Value就等於沒有意義了,因此能夠刪除。
相關文章
相關標籤/搜索