rocksdb-doc-cn

Rocksdb向用户提供了一系列API用于创建及导入SST文件。在你需要快速读取数据但是数据的生成是离线的时候,这非常有用。

创建SST文件

rocksdb::SstFileWriter可以用于创建SST文件。创建了一个rocksdb::SstFileWriter 对象之后,你可以打开一个文件,插入几行数据,然后结束。

这里有一个例子,展示了如何创建SST文件/home/usr/file1.sst

Options options;
SstFileWriter sst_file_writer(EnvOptions(), options);
// Path to where we will write the SST file
std::string file_path = "/home/usr/file1.sst";

// Open the file for writing
Status s = sst_file_writer.Open(file_path);
if (!s.ok()) {
    printf("Error while opening file %s, Error: %s\n", file_path.c_str(),
           s.ToString().c_str());
    return 1;
}

// Insert rows into the SST file, note that inserted keys must be 
// strictly increasing (based on options.comparator)
for (...) {
  s = sst_file_writer.Put(key, value);
  if (!s.ok()) {
    printf("Error while adding Key: %s, Error: %s\n", key.c_str(),
           s.ToString().c_str());
    return 1;
  }
}

// Close the file
s = sst_file_writer.Finish();
if (!s.ok()) {
    printf("Error while finishing file %s, Error: %s\n", file_path.c_str(),
           s.ToString().c_str());
    return 1;
}
return 0;

现在我们有了一个在/home/usr/file1.sst的SST文件了。

注意:

参考nclude/rocksdb/sst_file_writer.h 了解更多的内容

导入SST文件

导入SST文件非常简单,你所需要做的只是调用DB::IngestExternalFile()然后把文件地址以std::string的vector传入就行了

IngestExternalFileOptions ifo;
// Ingest the 2 passed SST files into the DB
Status s = db_->IngestExternalFile({"/home/usr/file1.sst", "/home/usr/file2.sst"}, ifo);
if (!s.ok()) {
  printf("Error while adding file %s and %s, Error %s\n",
         file_path1.c_str(), file_path2.c_str(), s.ToString().c_str());
  return 1;
}

参考include/rocksdb/db.h了解更多内容

导入一个文件的时候发生了什么?

当你调用DB::IngestExternalFile()我们会:

我们选择LSM树中满足以下条件的最低的一个层

全局序列号

通过SstFileWriter创建的文件的元信息块里有一个特别的名为全局序号的字段,当这个字段第一次被使用,这个文件里的所有key都认为自己拥有这个序列号。当我们导入一个文件,我们给文件里的所有key都分配一个序列号。RocksDB 5.16之前,RocksDB总是用一个随机写来更新这个元数据块里的全局序列号字段。从RocksDB 5.16之后,RocksDB允许用户选择是否通过IngestExternalFileOptions::write_global_seqno更新这个字段。如果这个字段在导入的过程中没有被更新,那么RocksDB在读取文件的时候使用MANIFEST的信息以及表属性来推断全局序列号。如果底层的文件系统不支持随机写,这个路径就非常有效了。考虑到向后兼容,可以把这个选项设置为true,这样RocksDB 5.16或者更新的版本生成的SST文件就可被5.15或者更旧的Rocksdb也可以打开这个文件了。

下层导入

从5.5开始,IngestExternalFile加载一个外部SST文件列表的时候,支持下层导入,意思是,如果ingest_behind为true,那么重复的key会被跳过。在这种模式下,我们总是导入到最底层。文件中重复的key会被跳过,而不是覆盖已经存在的key。

使用场景

回读部分历史数据,而不覆盖最新的数据。这个选项只有在DB一开始运行的时候增加了allow_ingest_behind=true选项才可以使用。所有的文件都会被导入到最底层,seqno=0

看到这里或许你有建议或者疑问或者指出错误,请留言评论! 多谢! 你的评论非常重要!也可以帮忙点赞收藏转发!多谢支持! 觉得写的不错那就给点吧, 在线乞讨 微信转账