前面学习了一下rocksdb,这个db是对leveldb的一个改进,是基于leveldb1.5的版本上的改进,并且leveldb1.5之后也在不断的优化,下面从写入性能对二者进行对比。函数
前言
比较的leveldb的版本是1.18,rocksdb的版本是3.10.1.post
在比较的时候须要将leveldb和rocksdb的参数调成同样的,本文的参数为,性能
memtable 4M,最多2个memtable学习
level0_slowdown_writes_trigger=8,level0_stop_writes_trigger=12,level0_file_num_compaction_trigger=4,测试
flush和compaction共用一个进程优化
leveldb和rocksdb在后台进程管理的默认配置也是不同的,leveldb默认只能有一个后台进程用于flush和compaction,而rocksdb flush和compaction都会有一个进程,本文特殊没有说明的rocksdb就是和leveldb同样的,flush和compaction共用一个进程atom
场景1
每一个key 8byte,没有valuespa
这个场景在关系链系统里面很是常见,由于关系链系统是key-list,使用leveldb相似系统实现的时候,须要将list中的id提到key里面线程
获得的测试结果以下:指针
leveldb | rocksdb | |
请求数 | 10000000 | 10000000 |
数据量 | 80M | 80M |
耗时s | 56 | 73 |
吞吐量(Mps) | 1.428571429 | 1.095890411 |
qps | 178571.4286 | 136986.3014 |
是否发生stall | 否 | 否 |
结论是leveldb比rocksdb要略胜一筹,因为value为空,整个的吞吐量和磁盘的吞吐量(100Mps到150Mps)还相差比较远,因此并无发生写stall的状况。由于没有发生stall,因此性能对比彻底是内存操做的性能的对比。
这个场景比的主要是内存的写操做速度,能够看出leveldb要好一些。
由于主要是内存操做,内存操做没有log,(加上log会严重影响性能),猜想的缘由多是:
- leveldb的skiplist的原子指针用的是memory barrier实现的,而rocksdb使用的atomic实现的。
- rocksdb采用了不少虚函数的地方,性能有可能比leveldb要差一些。
场景2
每一个key 8byte,value 1000byte。
leveldb | rocksdb(flush和compaction共用线程) | rocksdb(flush和compaction分开线程) | |
请求数 | 1000000 | 1000000 | 1000000 |
数据量 | 1G | 1G | 1G |
耗时s | 70 | 138 | 125 |
吞吐量(Mps) | 14.62857143 | 7.420289855 | 8.192 |
qps | 14285.71429 | 7246.376812 | 8000 |
是否发生stall | 是 | 是 | 是 |
结论仍然是leveldb要更好一些,具体查看LOG文件,能够看出端倪,rocksdb的最后的level分布是:[6 359 148 0 0 0 0],level1文件严重超出范围,这样level0的文件并到level1上的时候就须要读入很是多的文件。咋
其中一次8个level0的319个level1的文件进行一次compaction,花费的时间可想而知。
那么为何会这样呢?由于rocksdb在挑选compaction的时候,若是level0的文件数目超出level0_slowdown_writes_trigger的时候得分异常高,因此会一直发生level0向level1转移的状况,没有机会level1向level2转移。在这种状况下rocksdb就走向了深渊。。。。leveldb挑选compaction的时候,level0的分值是文件数目除以kL0_CompactionTrigger,其余level的分值是该level的总文件大小除以这个level的最大byte
当rocksdb的flush和compaction分为两个进程的时候时间稍有减小,能够看出效果很不明显。这个缘由是磁盘是瓶颈,分为两个进程并不能提升磁盘的吞吐量。
结论
从这个比较中能够看出,在写量很是大的时候,leveldb的性能仍是要优于rocksdb的