RocksDB 是存储同质对象的好选择吗?

Is RocksDB a good choice for storing homogeneous objects?

我正在寻找 C++ 中的可嵌入数据存储引擎。 RocksDB 是一个键值存储。

我的数据非常均匀。我有少量类型(大约 20 个),并且我存储了这些类型的许多实例(大约 100 万个)。

我想我的数据的同质性​​使 RocksDB 成为一个糟糕的选择。如果我单独序列化每个对象,我肯定会复制模式元数据吗?这肯定会导致性能不佳吗?

所以我的问题是:RocksDB 是存储同类对象的好选择吗?如果是这样,如何避免复制模式元数据对性能的影响?

据我了解,RocksDB 实际上是一个 KeyValue 存储,根本不是数据库。 这意味着您只能使用存储二进制键和值数据的工具。与普通数据库(例如 MySQL、SQLite)不同,您无法获得可以定义 columns/types 等的表。

因此,由您的程序决定数据的存储方式。

一种可能性是将您的数据存储为 JSON 值,在这种情况下,如您所说,您需要支付存储 "schema"(即 JSON 字段名称)的费用值。

另一种选择可能是,您有一个名为 SCHEMA 的特殊键(例如),其中包含所有对象类型的 AVRO 模式。你的应用程序可以在启动时读取它,初始化 readers/writers,然后它知道如何处理存储在 RocksDB 中的每个键+值。

另一种选择可能是您在应用程序中对逻辑进行硬编码。您可以为此使用任意数量的库,包括 AVRO(如上所述)或 MsgPack 及其变体。在这种情况下,如果您打算使用以前版本的应用程序中的 RocksDB 数据,如果您进行了任何模式更改,则需要小心。所以也许在数据库中存储版本号或其他东西。

与 sqlite 等不同,RocksDB 中没有模式元数据,因为没有模式:它将二进制键映射到二进制值。 RocksDB 没有内置序列化。如果要存储对象,则必须自己序列化它们并使用例如键、键前缀或列族(~ DB tables light)来区分类型。

通常您会使用 RocksDB 来构建某种自定义数据库。例如,有人在其之上构建了一个用于 protobuf 对象的缓存 (ProfaneDB)。通常我会说它太底层了,但如果你不需要结构化数据和查询,它会工作得很好,速度非常快,而且通常使用起来很愉快(他们的代码是可读的,有时是最好的文档,因为您将处理数据库内部结构)。

我以前在一个小玩具应用程序中使用过 varint 键前缀,它只需要一个字节开销,最多 127 种类型,但列族可能更适合产品应用程序。它们也有固定的开销,可以单独调整、添加、删除和管理。我不会为了几个字节而放弃您从它们那里获得的附加功能。如果你使用 RocksDB,这也大致代表了你处理问题的级别。