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

文件构造

在磁盘上的文件分为多个level,其中,level 0是非凡的,它蕴含了刚刚被flush的Memtable,因而存在level 0中的数据会比其余level更新。此外,Level 0的各文件之间并不是有序的,而其余Level中的各个sstfile间是有序的,如下图

这意味着除Level 0之外的其余Level都能够通过二分搜寻来精确地定位key的地位,而Level 0则不行。因为这个起因,Level 0的文件数目须要被严格控制。

除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