2

Compaction是RocksDB中很重要的机制,而RocksDB默认采用Leveled Compaction策略。因此先着重分析Leveled Compaction

文件结构

截屏2021-12-11 21.14.05.png

在磁盘上的文件分为多个level,其中,level 0是特殊的,它包含了刚刚被flush的Memtable,因此存在level 0中的数据会比其他level更新。此外,Level 0的各文件之间并不是有序的,而其他Level中的各个sstfile间是有序的,如下图
截屏2021-12-11 21.17.37.png
这意味着除Level 0之外的其他Level都可以通过二分搜索来准确地定位key的位置,而Level 0则不行。因为这个原因,Level 0的文件数目需要被严格控制。
截屏2021-12-11 21.19.20.png
除Level 0之外的其他Level都有目标大小,这些目标大小一般呈指数级别增长

当L0层的文件数据达到level0_file_num_compaction_trigger,compaction会被触发,L0层的文件将会merge到L1层。由于L0层的SST文件之间是无序的,可能有重叠的部分,所以在做compaction时,正常会将L0层的所有文件全部merge sort后写到L1层。

在这次Compaction后,L1层的文件大小可能会超过目标大小,这种情况下,L1中的至少一个文件会被merge到L2中

需要注意的是,L1及以下Level的Compaction是并行的。而默认情况下,L0到L1压缩不是并行的。在某些情况下,它可能成为限制Compaction速度的瓶颈。RocksDB仅支持L0到L1的基于子压缩的并行化。要启用它,可以将max_subcompactions设置为大于1。然后,RocksDB将尝试对范围进行分区,并使用多个线程来执行它:

Compaction挑选

当多个Level触发Compaction机制时,RocksDB需要决定先对哪个Level做Compaction。为了区分优先级,对每个Level计算相应的Score

  • 对于非L0层的层,score的计算方式为,level中所有sstfile的大小除以该level对应的目标大小(如果需要Compaction的文件已被选中,它将不包含在level总大小中)
  • 对于L0,score为(l0文件的总数量除以level0_file_num_compaction_trigger)和(总大小减去max_bytes_for_level_base)的最大值。 需要注意的是,如果文件数量小于level0_file_num_compaction_trigger,即使score再高,也不会从L0触发compaction

1iin
4 声望3 粉丝

Move on.