固定大小键的最快持久键/值数据库,仅插入/获取(无删除/更新)?

Vin*_*lco 5 database acid nosql leveldb rocksdb

鉴于持久键/值存储的以下要求:

  • 只需要获取、插入和所有值的完整迭代(用于导出)
  • 不删除值或更新值
  • 键的大小始终相同
  • 嵌入在宿主应用程序中的代码

鉴于这种使用模式:

  • 获取是随机的
  • 插入和获取是交错的,没有可预测性
  • 密钥是随机的,并以随机顺序插入

鉴于要求,最好的磁盘数据结构/算法是什么?

自定义实现能否超过基于 LSM(日志结构化合并)的实现(即 leveldb、rocksdb)的性能?

满足这些要求的高性能自定义实现在实现上是否也会相当简单?

kee*_*lar 5

虽然可能有更好的性能自定义实现来满足您的需求,但在您的情况下,配置良好的 RocksDB 应该能够击败大多数此类自定义实现。这是我将配置 RocksDB 的内容:

首先,由于您没有更新和删除,因此最好将所有数据压缩到 RocksDB 中的大文件中。因为 RocksDB 以可定制的顺序对这些键进行排序,所以拥有一些大文件可以提高读取性能,因为跨一些大文件的二进制搜索比跨多个小文件更快。通常,大文件会影响压缩的性能——在 RocksDB 中重组大部分数据的过程,以便 1. 与单个键关联的多个更新将被合并;2. 执行删除以释放磁盘空间;3. 保持数据排序。但是,由于您没有更新和删除,拥有大文件可以提供快速的读写性能。

其次,为布隆过滤器指定大位,当您可能在 RocksDB 中不存在键的情况下发出一些查询时,这允许您避免大多数 IO。

所以读请求是这样的。首先,它将查询键与那些大文件的键范围进行比较,以确定查询键可能位于哪个文件。然后,一旦键范围覆盖查询键的文件,它将计算查询键的布隆位以查看查询键是否可能存在于这些文件中。如果是这样,则将触发每个文件内的二进制搜索以识别匹配的数据。

至于扫描操作,由于 RocksDB 内部按照用户可自定义的顺序对数据进行排序,因此使用 RocksDB 的迭代器可以非常高效地完成扫描。

有关 RocksDB 基础知识的更多信息可以在这里找到。