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文件写入哪一层。

猜你喜欢

转载自www.cnblogs.com/shijiaqi1066/p/12459678.html