LevelDB Compaction

简介

LevelDB 中的 Compaction 分为两种,Minor Compaction 和 Major Compaction 。

Minor Compaction

Minor Compaction 将内存中的 MemTable dump 到外存,产生一个 SSTable 文件。

此外,Minor Compaction 优先级高于 Major Compaction 。

Major Compaction

Major Combination 用于 level 间的 merge ,一次合并将层 i 的一个 SSTable 合并到层 i+1 。

  • 对于 level > 0 的 SSTable,选择其中一个 SSTable 与 下一层 SSTable 做合并
  • 对于 level-0 的 SSTable,会将 SSTable 合并成多个不重叠的 1 层 SSTable 。

触发时机

当 0 层 SSTable 数超过阈值(默认为 4)
由于 Compaction 的其中一个目的是为了提高读取的效率,因此 LevelDB 不允许 0 层存在过多的文件数,一旦超过了上限值,即可进行 Major Compaction。
当 level-i 层 SSTable 的总大小超过阈值(10^i MB)
对于level i(i >= 1)的情况来说,一个读取最多只会访问一个 SSTable 文件,因此,SSTable 数对于读取效率的影响不会太大。针对于这部分数据发生 Compaction 的条件,从提升读取效率转变成了降低 Compaction 的 IO 开销。此外,这也有助于减低 Compaction 的开销。
当某个 SSTable 无效读取的次数过多 :

Compaction 与版本

需要注意到,每次 Compaction 后,LevelDB 的持久化数据的 Snapshot (亦即 SSTable + WAL) 的版本就发生变化了。

Compaction 速度问题

注意到 Compaction 存在两个问题:

  • Compaction 对外存 I/O 带宽的挤占
  • Compaction 可能跟不上 MemTable 的写入速度

所以 LevelDB 规定了两个变量:

  • 当 0 层文件数量超过 SlowdownTrigger 时,写入的速度主要减慢
  • 当 0 层文件数量超过 PauseTrigger 时,写入暂停,直至 Major Compaction 完成

评价

  • 消耗 CPU 和 I/O 资源
  • 缓存失效

这两者可能引起毛刺,一种方式是限速,但也不能限速太过。

写放大分析

  • +1 - WAL 的写入。
  • +1 - Immutable Memtable 写入到 level-0 文件。
  • +2 - level-0 和 level-1 的 compaction(level-0 的每个 SSTable 的 key 范围是重叠的。一般控制 level-0 和 level-1 的数据大小是一样的,每次拿全量 level-0 的数据和全量 level-1 的数据进行 compaction)。
  • +11 - level-n 和 level-n+1 合并的写入(n >= 1,默认情况下,level-n+1 的数据大小是 level-n 的 10 倍)。

总的写放大是 4 + 11(n-1) = 11n - 7 倍。

参考资料

https://zhuanlan.zhihu.com/p/149808938


hermit

knowledge

209 Words

0001-01-01 07:36 +0736