RocksDB-2个相同键值的Put操作后的双倍数据库大小

问题描述

我有一个使用RocksDB的程序,试图将大量的键值对写入数据库

int main() {
DB* db;
Options options;
// Optimize RocksDB. This is the easiest way to get RocksDB to perform well
options.IncreaseParallelism(12);
options.OptimizeLevelStyleCompaction();
// create the DB if it's not already present
options.create_if_missing = true;
// open DB
Status s = DB::Open(options,kDBPath,&db);
assert(s.ok());

for (int i = 0; i < 1000000; i++)
{
    // Put key-value
    s = db->Put(WriteOptions(),"key" + std::to_string(i),"a hard-coded string here");
    assert(s.ok());
}
delete db;
return 0;
}

当我第一次运行该程序时,它生成了大约2GB的数据库,并且尝试多次运行该程序,没有进行任何更改,我得到了N * 2GB的数据库N=number-of-run。直到一定数量的N,数据库大小才开始减小。 但是我所期望的是,如果每次运行后写入的数据库的新批次数据都保持不变,则应将其覆盖->然后,每次运行之后,数据库的大小应为〜2GB。

问题:这是RocksDB的问题吗?如果不是的话,在有相似的成对键值对的情况下,可以通过什么适当的设置来保持数据库的大小稳定?

解决方法

完全压缩可以减少空间使用,只需在delete db;之前添加以下行:

db->CompactRange(CompactRangeOptions(),nullptr,nullptr);

注意:一次完全压缩需要一些时间,具体取决于数据大小。

预计空间会放大,所有LSM tree data structure个DB都会出现此问题:https://github.com/facebook/rocksdb/wiki/RocksDB-Tuning-Guide#amplification-factors

这是一篇有关rockdb的空间放大研究的好论文:http://cidrdb.org/cidr2017/papers/p82-dong-cidr17.pdf

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...