Google的leveldb是个很优秀的存储引擎,但还是有一些不尽人意的地方,比如leveldb不支持多线程合并,对key范围查找的支持还很简单,未做优化措施,等等。而Facebook的RocksDB是个更彪悍的引擎,实际上是在LevelDB之上做的改进,在用法上与LevelDB非常的相似,两者的对比可以参考下面的参考资料1。
这里之所以要调研rocksdb是因为rocksdb中加入了prefix bloomfilter的实现,能够支持对范围查找的优化,对我目前的项目很有参考意义,下面是我调研和剖析rocksdb部分源码总结出的部分结果。
1. 对RocksDB中与Bloomfilter相关的调研结果
这一步主要参考rocksdb的官方博客和相关讨论,总结得到以下信息:
(1)rocksdb支持在key的sub-part上设置Bloomfilter,这使得范围查询成为可能。
(2)将key分为prefix和suffix,配置了一个prefix_extractor 来指定key-prefix,并用此存储每个key-prefix的blooms,然后用指定了prefix的iterator来使用这些bloom bits避免查询那些不包含所指定prefix的keys,从而实现了prefix过滤。
(3)Rocksdb实现了两个Bloomfilter,一个是在读block之前使用Bloomfilter过滤不包含key的blocks(与leveldb相同),另一个是在查询memtable时动态生成一个bloomfilter实现内存中的key过滤(在block read之前)。
上面这些信息源主要来自以下几个参考资料:
- Official Blog
- HackNews中关于rocksdb特性的讨论
- RocksDB Basics
2. rocksdb中Get接口实现优化(与leveldb对比)
下面简单总结下rocksdb中Get接口实现过程中的一些优化技术,总体实现流程与leveldb一致,都是memtable —>immemtable—>sstable的过程,但实现细节有所不同,主要有下面几点不同:
(1)memtable/ immemtable的Get实现(memtable.cc::Get)
Rocksdb在这个过程中加入了Bloomfilter机制,如下:
if (prefix_bloom_&&
!prefix_bloom_->MayContain(prefix_extractor_->Transform(user_key))){
// iter is null if prefix bloom says thekey does not exist
} else {