FIFO 压缩风格是最简单的压缩策略。很适合用于保存不是那么重要的事件日志数据(例如查询日志)。他会周期性删除旧的数据,所以基本来说,他是一种 TTL 压缩风格。
在 FIFO 压缩里,所有的文件都在 Level 0。当数据的总大小超过 CompactionOptionsFIFO::max_table_files_size 配置的大小时,我们删除最老的表文件。这意味着数据的写放大总是 1(还有 WAL 的写放大)
目前,CompactRange 函数只是强制触发压缩,然后如果有需要,删除旧的表文件。他忽略函数的参数(开始和结束 key)
由于我们不会重写键值对,我们也不会对 key 执行压缩过滤器方法。
请小心使用 FIFO 压缩风格。与其他压缩风格不同,他可能在不通知用户的情况下删除数据。
压缩¶
FIFO 压缩可能会导致大量 L0 文件。查询可能会变得很慢,因为最坏情况下,我们可能需要搜索所有的这些文件。即使是 bloom 过滤器也可能无法得到一个好的性能。加入有 1% 的假阳性结果,1000 个 L0 文件平均会导致 10 个假阳性结果,然后在最坏情况下,每个查询会生成 10 个 IO。用户可以选择使用更多的 bloom 位来减少假阳性结果,但是他们需要为此付出更多的内存。在某些情况下,bloom 过滤器检查的 CPU 开支可能会过高。
为了解决这个问题,用户可以选择允许一些轻量压缩发生。这可能会让写 IO 变成两倍,但是可以显著减少 L0 的文件。某些时候对于用户来说是合理的权衡。
这个功能在 5.5 版本中引入。用户可以通过 CompactionOptionsFIFO.allow_compaction = true 来打开这个功能。他会尝试选择至少 level0_file_num_compaction_trigger 个从 memtable 落盘的文件,然后合并他们。
特别的,我们总是从最新的 level0_file_num_compaction_trigger 文件开始,尝试包含尽可能多的文件进行压缩。我们使用 total_compaction_size / (number_files_in_compaction - 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 删除的文件也变大了,所以可能排序好的数据会比没有压缩的数据略微少一点。
FIFO 带 TTL 压缩¶
一个新的,名为 FIFO 带 TTL 压缩的功能在 RocksDB5.7 被引入。
目前,FIFO 压缩目前只考虑文件总大小,比如:如果 db 的大小超过 compaction_options_fifo.max_table_files_size,丢弃最老的文件,一个个地删除知道总大小小于阈值。有时候,生产环境上打开这个,会随着有机增长把生产环境搞乱。
一个新的选项,compaction_options_fifo.ttl,被引入,用来删除超过 TTL 的 SST 文件。这个功能允许用户根据时间丢弃文件而不总是根据大小来,比如说,丢弃所有一周前或者一个月前的数据。
限制:
- 这个选项目前只在 max_open_files 为 -1 时,对基于块的表格式使用。
- FIFO 带 TTL 仍旧在配置的大小范围内工作,比如说,如果观察到 TTL 无法让文件总数量少于配置的大小,RocksDB 会暂时下降到基于大小的 FIFO 删除。