RocksDB. Leveled Compaction原理分析

一 RocksDB的磁盘数据组织层次

1 磁盘文件的组织方式

rocksdb在磁盘上的文件是分为多层的,分别叫做level-0, level-1等等
level0上包含的文件,是由内存中的memtable dump到磁盘上生成的,单个文件内部按key有序,文件之间无序。
其它level上的多个文件都是按照key有序的。

RocksDB. Leveled Compaction原理分析_第1张图片
sst文件在磁盘上的组织方式

2 data range partition

非0 level上的key,按序分片,保存在不同的文件中。

RocksDB. Leveled Compaction原理分析_第2张图片
data range partition

3 key在SST文件中查找

每个level的文件都是整体有序,并且文件内有序的。
要在某个level上查找某个key时:

  • 先根据每个文件的start/end key对所有文件进行二分查找来确定哪些文件可能包含key
  • 再通过二分查找在候选的文件中定位key的准确位置
    这是一次对一个level上所有文件的二分查找的过程。

二 数据压缩 Compaction

1 L0 compaction

当L0的文件数量达到level0_file_num_compaction_trigger的值时,触发L0和L1的合并。通常必须将所有L0的文件合并到L1中,因为L0的文件的key是有交叠的(overlapping)。

RocksDB. Leveled Compaction原理分析_第3张图片
L0与L1的compaction

2 高层Compaction

当L0 compaction完成后,L1的文件总size或者文件数量可能会超过阈值,触发L1向L2的合并。从L1至少选择一个文件,合并到L2中key有交叠的文件中。

RocksDB. Leveled Compaction原理分析_第4张图片
L1向L2合并

同样的,合并后可能会触发下一各level的compaction。

RocksDB. Leveled Compaction原理分析_第5张图片
合并后的L2
RocksDB. Leveled Compaction原理分析_第6张图片
L2向L3合并

合并后的L3也需要做Compaction.


RocksDB. Leveled Compaction原理分析_第7张图片
合并后的L3

3 并行Compaction

RocksDB. Leveled Compaction原理分析_第8张图片
并行compaction

max_background_compactions控制了并行compaction的最大数量。

4 L0 subcompaction

L0向L1的compaction不可以与其他level compaction并行。这可能成为整体compaction速度的瓶颈,可以通过设置max_subcompactions来加速L0到L1的compaction。

RocksDB. Leveled Compaction原理分析_第9张图片
subcompaction

5 Compaction的选择策略

当多个level都满足触发compaction的条件,rocksdb通过计算得分来选择先做哪一个level的compaction。

  • 对于非0 level,score = 该level文件的总长度 / 阈值。已经正在做compaction的文件不计入总长度中。
  • 对于L0,score = max{文件数量 / level0_file_num_compaction_trigger, L0文件总长度 / max_bytes_for_level_base} 并且 L0文件数量 > level0_file_num_compaction_trigger。
    得分最高的level有限做compaction。

6 compaction触发阈值

每一层的compaction阈值设置策略由level_compaction_dynamic_level_bytes来决定。

当level_compaction_dynamic_level_bytes为false

L1 触发阈值:max_bytes_for_level_base
下面的level触发阈值通过公式计算:Target_Size(Ln+1) = Target_Size(Ln) * max_bytes_for_level_multiplier * max_bytes_for_level_multiplier_additional[n]. max_bytes_for_level_multiplier_additional

例如:
max_bytes_for_level_base = 16384
max_bytes_for_level_multiplier = 10
max_bytes_for_level_multiplier_additional = 1
那么每个level的触发阈值为 L1, L2, L3 and L4 分别为 16384, 163840, 1638400, and 16384000

当level_compaction_dynamic_level_bytes为true

最后一个level的文件长度总是固定的。
上面level触发阈值通过公式计算:Target_Size(Ln-1) = Target_Size(Ln) / max_bytes_for_level_multiplier
如果计算得到的值小于 max_bytes_for_level_base / max_bytes_for_level_multiplier, 那么该level将维持为空,L0做compaction时将直接merge到第一个有合法阈值的level上。
例如:
max_bytes_for_level_base = 1G
num_levels = 6
level 6 size = 276G
那么从L1到L6的触发阈值分别为:0, 0, 0.276G, 2.76G, 27.6G,276G。

这样分配,保证了稳定的LSM-tree结构。并且有90%的数据存储在最后一层,9%的数据保存在倒数第二层。

RocksDB. Leveled Compaction原理分析_第10张图片
image.png

参考资料:官方wiki

你可能感兴趣的:(RocksDB. Leveled Compaction原理分析)