给定持久键/值存储的以下要求:
- 只需要获取、插入和完整迭代所有值(用于导出)
- 不删除值或更新值
- 键总是相同的大小
- 嵌入在主机应用程序中的代码
并给出这种使用模式:
- 抓取是随机的
- 插入和提取是交错的,没有可预测性
- 密钥是随机的,并以随机顺序插入
给定要求,最好的磁盘数据结构/算法是什么?
自定义实现能否超越基于 LSM(Log Structured Merge)的实现(即 leveldb、rocksdb)的性能?
满足这些要求的高性能定制实现在实现上是否也会相当简单?
虽然可能有更好的性能自定义实现来满足您的要求,但在您的情况下,配置良好的 RocksDB 应该能够击败大多数此类自定义实现。这是我要配置 RocksDB 的内容:
首先,由于您没有更新和删除,因此最好将所有数据压缩到 RocksDB 中的大文件中。由于 RocksDB 以可自定义的顺序对这些键进行排序,因此拥有一些大文件可以让您获得更快的读取性能,因为跨一些大文件的二进制搜索比跨多个小文件更快。通常,拥有大文件会损害压缩的性能 --- 重组 RocksDB 中大部分数据的过程,以便 1. 与单个键关联的多个更新将被合并;2. 执行删除以释放磁盘空间;3. 保持数据排序。但是,由于您没有更新和删除,因此拥有大文件可为您提供快速的读写性能。
其次,为bloom filter指定大位,当您可能发出一些在RocksDB中不存在键的查询时,这可以避免大多数IO。
所以一个读请求是这样的。首先,它将查询键与那些大文件的键范围进行比较,以确定查询键可能位于哪个文件。然后,一旦 key-range 的文件覆盖了查询 key,它将计算查询 key 的bloom bits 以查看这些文件中是否存在查询 key。如果是这样,则将触发每个文件内的二进制搜索以识别匹配的数据。
至于扫描操作,由于 RocksDB 内部按照用户自定义的顺序对数据进行排序,因此使用 RocksDB 的迭代器可以非常高效地完成扫描。
关于 RocksDB 基础的更多信息可以在这里找到。