我正在开发类似于Apache Cassandra和LevelDB的键值数据库。
它使用LSM trees
(https://en.wikipedia.org/wiki/Log-structured_merge-tree)
键是字符串,我使用的是C ++。
目前,数据存储在磁盘上的几个IMMUTABLE" sstables",每个都有两个文件。
数据文件 - " flat" file - 记录后记录,按键排序,没有任何磁盘块对齐。
索引文件 - 它包含每个记录的记录数和8字节数(uint64_t)的数组。您可以对数据文件中的任何记录进行定位(搜索)和查找偏移量。
我已将这两个文件映射到内存中。
如果我的程序需要找到一个记录,它会进行二分查找。然而,这意味着程序会进行大量的磁盘搜索。我做了一些优化,例如我实际上跳转搜索并顺序读取最后40-50条记录。但是在拥有10亿个密钥的情况下,它仍然会进行20-25次搜索(而不是30次)。
这一切都运行得非常快 - 对于没有虚拟内存缓存的10亿个密钥(例如,首次请求),以及使用虚拟内存缓存的1秒以下的方式,只需4-5秒。
但是我想在磁盘上构建一些额外的数据结构,可以加快查找速度。我想用#34; level ordered array&#34 ;,例如而不是:
1,2,3,4,5,6,7
是
4,2,6,1,3,5,7
在这种情况下,大多数使用过的密钥都位于文件的开头,但我并不是100%确定它会有多大帮助。
第二个虽然是做B Tree或B + Tree之类的东西,但是创建看起来非常复杂,很多磁盘同步 - 或者至少这是我看到的。
Apache Cassandra正在使用密钥样本 - 它在内存中有每第1024个密钥 - 由于内存消耗,我不想这样做。但是,如果我把它们安装在磁盘上,那就是"扁平"文件,它仍然需要很多寻找"样本"键。
我有什么替代方案吗?