gpt4 book ai didi

rocksdb - 使用RocksDB通过拆分容器来支持key-key-value(RowKey->Containers)

转载 作者:行者123 更新时间:2023-12-05 06:13:00 26 4
gpt4 key购买 nike

支持我有键/值,其中值是一个逻辑字符串列表,我可以在其中附加字符串。为了避免将单个字符串项插入队列导致重写整个列表的情况,我将使用多个键值对来表示它。

Key -> 值的元数据,例如长度和子键格式Key-l1 -> 列表中第 1 项的值Key-l2 -> 列表中第 2 项的值Key-ln -> 列表中的最新值

我将重写 RocksDB 中的键比较器,这样 Key-ln 格式键的排序首先是键部分排序,然后是 ln 部分排序(即分组依据并按键排序,在同一键值内按 ln 排序)。这样,在初始批量插入和稍后的 sst 压缩期间,所有列表项及其根键和元数据都在 sst 中分组在一起。

追加一个新的列表项就变成了(1)先读取Key-metadata得到当前列表大小n; 2) 插入具有新值的Key-l(n+1)。通过删除 Key-ln 并更新元数据,删除列表项与 RocksDB 一样。为了保证一致性,(1)和(2)将在一个RocksDB事务中完成。

这个设计好像还行吧?

现在,如果我想为整个键值(列表)添加 TTL 的另一个特性,我会在 RocksDB 中使用 TTL 支持。我的理解是 TTL 删除过期项目发生在压缩期间。但是,这种压缩不是在事务下完成的。 RocksDB 不知道 Key-metadata 和 Key-ln 条目是相关的。完全有可能存在一个时间窗口,Key->metadata(root node)被删除,而(Key-ln)的子节点还没有被删除(或者倒序)。如果在此时间窗口内,有人读取或更新列表,则会导致 key 列表不一致。有什么补救措施吗?

谢谢

最佳答案

你应该使用 Merge Operator ,它专为此类值(value)附加用例而设计。您的设计是 read-before-write,这会降低性能,通常应尽可能避免:What's read-before-write in NoSQL? .

Options options;
options.merge_operator.reset(new StringAppendOperator(','));
DB::Open(options, kDBPath, &db)
...
db->Merge(WriteOptions(), "key", "value1");
db->Merge(WriteOptions(), "key", "value2");

db_->Get(ReadOptions(), "key", &result); // return "value1,value2"

上面的例子使用了预定义的 StringAppendOperator ,它只是在末尾附加新值。您可以定义自己的 MergeOperator 来自定义合并操作。

在后端,对读取路径进行合并操作(并压缩以减少版本号),详情:Merge Operator Implementation .

关于rocksdb - 使用RocksDB通过拆分容器来支持key-key-value(RowKey->Containers),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63443856/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com