LevelDB Compaction原理


 

 

manual compaction

手動觸發的compaction。手動觸發的優先級高於自動觸發。

 

 

自動觸發的compaction

觸發條件:

imm_ != NULL 表示需要將Memtable dump成SSTable,發起Minor Compaction。
manual_compaction_ != NULL 表示手動發起Compaction。
versions_->NeedsCompaction函數返回True。

 

注意:在leveldb中,compaction的入口都在 DBImpl::MaybeScheduleCompaction() 

 

 

 

Memtable --> Immutable Memtable

Memtable:內存SkipList

簡單理解:從可讀可寫的Memtable變為可讀不可寫的Memtable。

當內存Memtable寫到一定量的時候,會生成新的wal log和新的Memtable。

 

minor compaction

immutable memtable dump成sstable文件。

Immutable Memtable --> Level0

該過程被成為minor compaction

Immutable Memtable會在后台線程中導出數據,flush到磁盤上,形成一個新的sstable文件。

注意:這個過程不刪除kv數據。刪除key的信息被記錄進sstable文件。

Level0文件會有多個文件,多個文件的keys range會有重復。

minor compaction主要做兩件事情:

1、構造sstable

2、新的sstable文件寫入哪一層。

 

 

代碼流程:

 

 

 

 要注意,新成出來的文件不一定處於level0。大都數情況都是level0。

創建出來的新文件處於的層數由PickLevelForMemTableOutput 函數計算。邏輯如下:

 

 

 

 

在策略上,盡量要將新的compact的文件推到高level。

因為在level 0 需要控制文件過多,compaction IO和查找都比較耗費。

另一方面也不能推至過高level,一定程度上控制查找的次數,而且若某些范圍的key更新比較頻繁,后續往高層compaction IO消耗也很大。

所以PickLevelForMemTableOutput就是個權衡折中。如果新生成的sstable和Level 0的sstable有交疊,新產生的sstable就直接加入level 0,否則根據一定的策略,向上推到Level1 甚至是Level 2,但是最高推到Level2。

這里有一個控制參數:kMaxMemCompactLevel。判斷sstable文件之間key是否有重疊要用到前面介紹的數據結構FileMetaData。

 

 

major compaction

當某個Level層級的文件數量超過一定閾值后,會從這個Level的sstable文件將其和高一層級的level+1的sstable文件進行compaction成為新的level+1層的文件。

觸發條件:

bool NeedsCompaction() const {
    Version* v = current_;
    return (v->compaction_score_ >= 1) || (v->file_to_compact_ != NULL);
  }

1. 文件數目太多或者某一層級文件總大小過大,會觸發compaction。

某一層及文件個數太多。(指的是level0)

或某一層級文件總大小太大。超過限制值。

 

2. seek次數太多,觸發compaction

除了level 0以外,任何一個level的文件內部是有序的,文件之間也是有序的。但是level(n)和level(n+1)中的兩個文件的key可能存在交叉。正是因為這種交叉,查找某個key值的時候,level(n) 的查找無功而返,而不得不去level(n+1)查找。如果查找了多次,某個文件不得不查找,卻總也找不到,總是去高一級的level,才能找到。這說明該層級的文件和上一級的文件,key的范圍重疊的很嚴重,這是不合理的,會導致效率的下降。因此,需要對該level 發起一次major compaction,減少 level 和level + 1的重疊情況。

這就是所謂的 Seek Compaction。對於seek觸發的compaction, 哪個文件無效seek的次數到了閾值,那個文件就是level n的參與compaction的文件。而size 觸發的compaction稍微復雜一點,它需要考慮上一次compaction做到了哪個key,什么地方,然后大於該key的第一個文件即為level n的參與compaction的文件。

對於n >0的情況,初選情況下level n的參與compaction文件只會有1個,如果n=0,因為level 0的文件之間,key可能交叉重疊,因此,根據選定的level 0的該文件,得到該文件負責的最小key和最大key,找到所有和這個key 區間有交疊的level 0文件,都加入到參戰文件。

 

 

 

 

 

由於level0的特殊性,所以major compaction要分分為兩種:

Level0  --> Level1

選擇一個level0文件。

再找到一個和該level0有重復key的level1文件。

再查找出所有和這個level1文件有重復key的level0文件。

將所有level0文件和level1文件合並成一個新的level1文件。

 

Level N --> Level N +1

選擇一個 Level N的文件

查找所有和該文件由重復key的Level N +1的文件。

compaction,生成新的Level N + 1的文件。

 

 

 

LevelN

 

 

 

 

 

 

minor compaction主要做兩件事情:1、構造sstable2、新的sstable文件寫入哪一層。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM