1

参考:

Remote Compaction机制使远程地Compaction成为可能,它可以是一个不同的进程,甚至是在远程的主机上。通过将Compaction服务迁移到远程的主机上,不会有后台的Compaction服务去影响read和write请求,提高了性能和稳定性。而专用于Compaction的远程主机可以只对Compaction做优化,并用来给不同的DB做Compaction。

截屏2022-01-15 11.45.56.png

Schedule

第一步是数据库触发Compaction,它不会在本地进行Compaction,而是在CompactionService中发送 Compaction信息。用户需要实现CompactionService::Start(),来发送Compaction信息给远端进程,从而调度Compaction

Compact

remote的Compaction Worker需要使用发来的Compaction信息运行DB::OpenAndCompact()。Worker会在只读模式下进行Compact,它不能修改LSM Tree,而是将Compact的结果放在一个暂时的位置。

Return Result

当Compaction结束后,需要向原先的那台db返回结果,包含Compact的SST的元数据和一些internal的信息,与调度环节中类似的,此处两台机器的通信需要被实现。

Install & Purge

原db通过CompactionService::WaitForComplete()等待结果返回,结果应该传入该函数并返回。在这之后,如果暂时工作区和db不在同一个文件系统上,需要先把暂时工作区的文件copy过去,然后再做重命名。
截屏2022-01-15 19.39.03.png

源码解读

include/rocksdb/options.h

include/rocksdb/options.h中,可以找到关于CompactionService的定义。

// Start the compaction with input information, which can be passed to
  // `DB::OpenAndCompact()`.
  // job_id is pre-assigned, it will be reset after DB re-open.
  // Warning: deprecated, please use the new interface
  // `StartV2(CompactionServiceJobInfo, ...)` instead.
  virtual CompactionServiceJobStatus Start(
      const std::string& /*compaction_service_input*/, uint64_t /*job_id*/) {
    return CompactionServiceJobStatus::kUseLocal;
  }

  // Start the remote compaction with `compaction_service_input`, which can be
  // passed to `DB::OpenAndCompact()` on the remote side. `info` provides the
  // information the user might want to know, which includes `job_id`.
  virtual CompactionServiceJobStatus StartV2(
      const CompactionServiceJobInfo& info,
      const std::string& compaction_service_input) {
    // Default implementation to call legacy interface, please override and
    // replace the legacy implementation
    return Start(compaction_service_input, info.job_id);
  }

  // Wait compaction to be finish.
  // Warning: deprecated, please use the new interface
  // `WaitForCompleteV2(CompactionServiceJobInfo, ...)` instead.
  virtual CompactionServiceJobStatus WaitForComplete(
      uint64_t /*job_id*/, std::string* /*compaction_service_result*/) {
    return CompactionServiceJobStatus::kUseLocal;
  }

  // Wait for remote compaction to finish.
  virtual CompactionServiceJobStatus WaitForCompleteV2(
      const CompactionServiceJobInfo& info,
      std::string* compaction_service_result) {
    // Default implementation to call legacy interface, please override and
    // replace the legacy implementation
    return WaitForComplete(info.job_id, compaction_service_result);
  }

其中,Start和WaitForComplete各有两个version,根据注释,应该是推荐使用最新的V2版本。

db/compaction/compaction_service_test.cc

Remote Compaction部分对Primary部分的实现主要在db/compaction/compaction_service_test.cc中。
其中有MyTestCompactionServiceLegacy和MyTestCompactionService两个类。前者应该是上个版本的遗留代码,使用的是V1的Start和WaitForComplete,而后者则是V2的。
这里主要对V2版本的这两个函数进行解析。

StartV2比较简短

CompactionServiceJobStatus StartV2(
      const CompactionServiceJobInfo& info,
      const std::string& compaction_service_input) override {
    InstrumentedMutexLock l(&mutex_);
    start_info_ = info;
    assert(info.db_name == db_path_);
    jobs_.emplace(info.job_id, compaction_service_input);
    CompactionServiceJobStatus s = CompactionServiceJobStatus::kSuccess;
    if (is_override_start_status) {
      return override_start_status;
    }
    return s;
  }

只是将job的id和input加入进map中,应该需要自行实现发送到远程的步骤。

WaitForCompleteV2中
最近的commit加入了fallback机制,如果remote compaction不成功,会fallback进行local compaction。
默认实现似乎仍是调用了本机的OpenAndCompact,需要进行修改。


1iin
4 声望3 粉丝

Move on.