当L0文件达到12个, 而compaction来不及的时候, 写入完全阻塞, 这个阻塞时间可能长达10s.
LevelDB实现上是L0达到4个时开始触发compaction, 8个时开始减慢写入, 12个时完全停止写入. 具体配置是写死的, 不过可以在编译时修改:
// Level-0 compaction is started when we hit this many files.
static const int kL0_CompactionTrigger = 4;
// Soft limit on number of level-0 files. We slow down writes at this point.
static const int kL0_SlowdownWritesTrigger = 8;
// Maximum number of level-0 files. We stop writes at this point.
static const int kL0_StopWritesTrigger = 12;
RocksDB这几个数字都可以通过参数设置, 相对来说好一些:
options.level0_slowdown_writes_trigger
options.level0_stop_writes_trigger
但是
一旦写入速度>compaction速度, 不论这几个阈值设置多大, L0都迟早会满的.
阈值调大会导致数据都堆积在L0, 而L0的每个文件key范围是重叠的,
意味着一次查询要到L0的每个文件中都查一下, 如果L0文件有100个的话,这大约就是100次IO, 读性能会急剧降低.
实际上, RocksDB的 Universal Style 就是把所有的数据都放在L0, 不再做compaction, 这样显然没有写放大了,
但是读的速度就更慢了, 所以限制单个DB大小小于100G, 而且最好在内存.