RocksDB 中的 LSM-tree Compaction 算法概述(三)- FIFO Compaction

FIFO compaction 适用于低负载数据的存储(如日志),所有的文件都位于 L0。当文件总大小超过配置值 CompactionOptionsFIFO::max_table_files_size (默认值为 1GB) 时,最早的 SST 文件将会被删除。

Compaction* FIFOCompactionPicker::PickSizeCompaction(
...
  std::vector inputs;
  inputs.emplace_back();
  inputs[0].level = 0;

  for (auto ritr = level_files.rbegin(); ritr != level_files.rend(); ++ritr) {
    auto f = *ritr;
    total_size -= f->compensated_file_size;
    inputs[0].files.push_back(f);
    char tmp_fsize[16];
    AppendHumanBytes(f->fd.GetFileSize(), tmp_fsize, sizeof(tmp_fsize));
    ROCKS_LOG_BUFFER(log_buffer,
                     "[%s] FIFO compaction: picking file %" PRIu64
                     " with size %s for deletion",
                     cf_name.c_str(), f->fd.GetNumber(), tmp_fsize);
    //  选择文件进行 compaction 直到文件总大小小于阈值
    if (total_size <=
        mutable_cf_options.compaction_options_fifo.max_table_files_size) {
      break;
    }
  }
...
}

L0 IntraCompaction

仅仅如此简单的 compaction 策略可能会因为 L0 保存了大量的 SST 文件导致查询性能急剧下降。即使有 bloom filter 的帮助,甚至可能严重到 bloom filter 的开销大到不可接受的地步。开启 CompactionOptionsFIFO.allow_compaction 参数,可以触发 L0 IntraCompaction,每次至少选取 level0_file_num_compaction_trigger 个 SST 文件进行合并,从而减少文件数量。
以 level0_file_num_compaction_trigger = 2,每个 flush 文件大小为 100MB 为例,其 compaction 过程如下:

100MB
100MB 100MB -> 200MB
100MB 200MB
100MB 100MB 200MB -> 200MB 200MB
100MB 200MB 200MB

TTL Compaction

TTL compaction 在 FIFO compaction 的基础之上,提供 SST 文件级别的过期删除功能。当 SST 的最新的 key 存在时间超过 mutable_cf_options.ttl,则该 SST 文件将会在 TTL compaction 中被删除。

Compaction* FIFOCompactionPicker::PickTTLCompaction(
    const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
    const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
    LogBuffer* log_buffer) {
 ...
  std::vector inputs;
  inputs.emplace_back();
  inputs[0].level = 0;

  // avoid underflow
  if (current_time > mutable_cf_options.ttl) {
    for (auto ritr = level_files.rbegin(); ritr != level_files.rend(); ++ritr) {
      FileMetaData* f = *ritr;
      assert(f);
      if (f->fd.table_reader && f->fd.table_reader->GetTableProperties()) {
        uint64_t creation_time =
            f->fd.table_reader->GetTableProperties()->creation_time;
        //  判断文件是否过期
        if (creation_time == 0 ||
            creation_time >= (current_time - mutable_cf_options.ttl)) {
          break;
        }
      }
      total_size -= f->compensated_file_size;
      inputs[0].files.push_back(f);
    }
  }
 ...

参考文献

RocksDB Compaction Wiki
RocksDB FIFO Compaction Wiki

你可能感兴趣的:(RocksDB 中的 LSM-tree Compaction 算法概述(三)- FIFO Compaction)