Level-1-Sub-Compaction

在 RocksDB 中,有配置项 max_subcompactions,在 Level Compaction Style 中,max_subcompactions 在两种情况下生效:

  1. L0 + L1 -> L1 compaction (更准确地说 output 不一定是 L1,但 input 一定有 L0)
  2. Manual Compaction

num_subcompact > 1 时,不同的 subcompact 会在多个线程中并发执行,对于覆盖了多个 subcompact 的 SST 文件,会在这多个 subcompact 线程中分别读取相应的部分,如果是发生在 DB 结点上对热数据的 compact,这没什么问题,因为读文件要通过操作系统 PageCache,即便多个线程访问,也有很大概率会命中 PageCache。

但是,如果 compact 的 input sst 是冷数据,PageCache 的利用率会降低!

这是因为:Compact 对 SST 文件是顺序访问,对于 subcompact 边界上的 SST 文件,后面一个 subcompact 最先访问的文件,在前一个 subcompact 是最后访问,此时之前加载到 PageCache 中的数据,可能已经被 evict 出去了!特别是对于 Topling SST,预加载的文件内容比例较大(不像 BlockBasedTable 只需加载 BlockIndex)。

Compact input sst 是冷数据分两种情况:

  1. DB 结点上对冷数据的 Compact
  2. 分布式Compact,对 Compact 结点而言,所有 SST 都是冷数据

所以,在 RocksDB 中,决定是启用 subcompact 的规则是非常合理的,因为 Manual Compact 用户可以用非0值来设置 CompactRangeOptions.max_subcompactions 以覆盖 DBOptions.max_subcompactions

max_level1_subcompactions

在 ToplingDB 分布式Compact 中,即便是 Manual Compact,我们也不希望启用 subcompact,那就只能在用户代码中设置 CompactRangeOptions.max_subcompactions = 1,而我们希望用户代码尽量不用修改,所以,我们新加了一个选项:DBOptions.max_level1_subcompactions

它默认情况下等于 DBOptions.max_subcompactions,但是不管在任何情况下,它只影响 start_level = 0 的 Compact。