Compaction(称为合并,或者压缩),在LSM中,指的是把数据从Ln层,合并到Ln+1层,把重复的旧的数据删除。
Compaction算法
主要两个类型的LSM树合并算法:
Leveled
-
leveled 合并,这个是RocksDB的默认策略
leveled 算法的特点是以读放大和写放大为代价最小化空间放大。
LSM-tree 可以看作是包含若干 level 的序列,每个 level 是仅包括1个 sorted run。相邻 level 的大小之比通常被我们称为 fanout(扇出),当不同 level 之间的 fanout 相同时,LSM-tree 的写放大最小。compaction 选择 L(n) 的数据,与原有 L(n+1) 的数据进行合并,得到新的 L(n+1) 数据。每次 compaction 的最大写放大系数等同于 fanout。
Tiered
-
一种替代合并策略,有时候被叫做“size tiered”或者“tiered”
Tiered合并通过增加读放大和空间放大,来最小化写放大 。
LSM-tree 依然可以看作是包含若干 level 的序列,每个 level 包括 N 个 sorted run。L(n) 的 sorted run 大小是 L(n-1) 的 N 倍。compaction 通常选择 L(n) 的数据合并得到新的 sorted run 输出到 L(n+1),但并不与 L(n+1) 的已有数据进行合并。每次 compaction 的最大写放大系数是 1。
两种算法的主要差别在于,leveled合并倾向于更加频繁的把小的排序结果合并到大的里面,而“tiered”等待多个大小接近的排序结果,然后把它们合并到一起。
-
Tiered+Leveled
Tiered+Leveled会有比leveled更小的写放大,以及比teired更小的空间放大。
Tiered+Leveled实现方式是一种混合实现,在小的层使用tiered,在大的层使用leveld。具体哪一层切换tiered和leveled可以非常灵活。
RocksDB中的Leveled合并也是Tiered+Leveled。一个memtable落盘过程类似于tiered合并——memtable的输出在L0构建一个新的排序结果并且不需要读/重写L0上已经存在的排序结果。根据level0_file_num_compaction_trigger的配置,L0可以有多个sort run,所以L0是Teired的。 其它层为Leveled。
RocksDB的Compaction
Rocksdb常用的Compaction模式有两种:Leveled、Universal(tiered算法)。
Leveled Compaction
所有非0层都有 target sizes。合并的目的是限制这些层的数据大小。target sizes通常指数增加。
当L0的文件数量到达level0_file_num_compaction_trigger,合并(compaction)就会被触发,L0的文件会被合并进L1。通常我们需要把所有L0的文件都选上&#x