FIFO 压缩样式

FIFO压缩样式是最简单的压缩策略。它适合以非常低的开销(例如查询日志)保存事件日志数据。 它周期性地删除旧数据,所以它基本上是一种TTL压缩样式。

在FIFO压缩中,所有文件都在0级。当数据的总大小超过配置的大小(CompactionOptionsFIFO::max_table_files_size)时,我们删除最老的表文件。 这意味着数据的写放大总是1(除了WAL写放大之外)。

目前,CompactRange()函数只是手动触发压缩,并在需要时删除旧表文件。 它忽略了函数的参数(开始和结束键)。

因为我们从来没有重写键值对,所以我们也从来没有对键应用过压缩过滤器。

请谨慎使用FIFO压缩方式。与其他压缩样式不同,它可以在不通知用户的情况下删除数据。

Compaction压缩

FIFO压缩可能会以大量L0文件结束。查询可能很慢,因为我们需要在查询中最坏的情况下搜索所有这些文件。即使是bloom过滤器也可能无法抵消所有这些影响。 在1%的典型假阳性情况下,1000个L0文件平均会导致10个假阳性,在最坏的情况下,每个查询生成10个I/Os。 用户可以选择使用更多的bloom位来减少假阳性,但是他们必须使用更多的内存。在某些情况下,甚至bloom filter检查的CPU开销也太高,无法接受。

要解决这种情况,用户可以选择启用一些轻量级压缩。这可能会使写I/O增加一倍,但可以显著减少L0文件的数量。 对于用户来说,这有时是正确的权衡。

该特性在5.5版本中引入。用户可以使用CompactionOptionsFIFO启用它。allow_compaction = true。它试图获取从memtable中刷新的至少level0_file_num_compaction_trigger文件,并将它们压缩在一起。

具体来说,我们总是从最新的level0_file_num_compaction_trigger文件开始,并尝试在压缩中包含更多的文件。 我们使用total_compaction_size / (number_files_in_compact - 1)计算每个文件的压缩字节数,我们总是选择这些文件,以使这个数字最小化,并且不超过options.write_buffer_size。 在典型的工作负载中,它总是会压缩level0_file_num_compaction_trigger新刷新的文件。

例如,如果level0_file_num_compaction_trigger = 8,并且每个刷新的文件都是100MB。然后,只要有8个文件,它们就被压缩为一个800MB的文件。 在我们有8个新的100MB文件之后,它们被压缩到第二个800MB中,以此类推。最终,我们将得到一个包含800MB文件的列表,而不超过8100mb的文件。

请注意,由于压缩了最老的文件,FIFO要删除的文件也更大,因此存储的数据可能比没有压缩的文件少一些。

用TTL进行FIFO压缩

在RocksDB 5.7中引入了一个名为使用TTL进行FIFO压缩的新特性。(2480)

到目前为止,FIFO压缩只考虑总文件大小,比如:如果db大小超过compaction_options_fifo,则删除最老的文件。 max_table_files_size,每次一个,直到总大小低于设置的阈值。这有时使在生产中启用变得棘手,因为用例可以有有机增长。

一个新选项compaction_options_fifo。,用于删除ttl已过期的SST文件。该特性允许用户根据时间删除文件,而不是总是根据大小删除文件, 例如,删除所有超过一周或一个月的SST文件。

约束:

  • 目前,这只适用于基于块的表格式和max_open_files设置为-1时。
  • 带有TTL的FIFO仍然在配置大小的范围内工作,也就是说,如果RocksDB发现删除过期文件不会使总大小小于配置的最大大小, 那么它将根据大小暂时回到FIFO删除。