共计 1080 个字符,预计需要花费 3 分钟才能阅读完成。
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