leveldb性能分析和表现

标签: Linux 源码分析 调优 leveldb | 发表时间:2011-05-30 12:02 | 作者:Yu Feng Adam
出处:http://blog.yufeng.info

原创文章,转载请注明: 转载自Erlang非业余研究

本文链接地址: leveldb性能分析和表现

Leveldb是一个google实现的非常高效的kv数据库,目前的版本1.2能够支持billion级别的数据量了。 在这个数量级别下还有着非常高的性能,主要归功于它的良好的设计。特别是LSM算法。

那么数据库最怕的的随机IO他是如何解决的呢?

先说随机写,它的写都是先记录到日志文件去的,在日志文件满之前只是简单的更新memtable,那么就把随机写转化成了顺序写。在日志满了后,把日志里面的数据排序写成sst表同时和之前的sst进行合并,这个动作也是顺序读和写。大家都知道传统磁盘raid的顺序读写吞吐量是很大的,100M左右是没有问题。在写日志文件的时候,用到是buffer IO,也就是说如果操作系统有足够的内存,这个读写全部由操作系统缓冲,效果非常好。即使是sync写模式,也是以数据累计到4K为一个单位写的,所以效率高。

那么随机读呢?这个它解决不了。但是ssd盘最擅长随机读了。这个硬件很自然的解决了这个问题。

所以leveldb的绝配是ssd盘的raid.

leveldb标准版本编译见这里,由于标准版本用到了c++ 0x的特性,在RHEL平台下没得到支持,所以为了移植性, basho见这里为它做了标准c++版本的port, 见目录c_src/leveldb. 他之所以用c++ 0x标准主要是用到里面的原子库,basho的port用了libatomicops搞定这个问题.

我们的测试采用的就是这个版本, 我们分别测试了1000万, 1亿,10亿数据量下的leveldb表现,发现随着数据集的变化性能变化不大。
由于leveldb默认的sst文件是2M, 在数据集达到100G的时候要占用几万个文件,我修改了:

version_set.cc:23 static const int kTargetFileSize = 32 * 1048576;

让默认的文件变成32M,减少目录的压力。

我的测试环境是:

$uname -r
2.6.18-164.el5 #RHEL 5U4
# 10* SAS 300G raid卡,fusionIO 320G, Flashcache,内存96G,  24 * Intel(R) Xeon(R) CPU

top说:

21782 root      18   0 1273m 1.1g 2012 R 85.3  1.2   1152:34 db_bench

iostat说:

$iostat -dx 5
...
sdb1              0.40     0.00  3.40  0.00    30.40     0.00     8.94     0.02    4.65   4.65   1.58
fioa              0.00     0.00 2074.80  3.80 16598.40    30.40     8.00     0.00    0.13   0.00   0.00
dm-0              0.00     0.00 1600.00  0.00 16630.40     0.00    10.39     0.25    0.15   0.15  24.76
...

该测试中请注意snappy压缩没有打开,如果有压缩性能还会高很多,因为IO少了一半。
write_buffer_size=$((256*1024*1024)),log大小设成256M,这样减少切换日志的开销和减少数据合并的频率。

同时应该注意到db_bench是单线程程序,还有一个compact线程,所以最多的时候这个程序只能跑到200%的cpu, IO util也不是很高. 换句话说如果是多线程程序的话性能还要N倍的提高。

我们来看下实际的性能数字:


#1千万条记录
$sudo ./db_bench --num=10000000 --write_buffer_size=$((256*1024*1024))
LevelDB:    version 1.2
Date:       Fri May 27 17:14:33 2011
CPU:        24 * Intel(R) Xeon(R) CPU           X5670  @ 2.93GHz
CPUCache:   12288 KB
Keys:       16 bytes each
Values:     100 bytes each (50 bytes after compression)
Entries:    10000000
RawSize:    1106.3 MB (estimated)
FileSize:   629.4 MB (estimated)
write_buffer_size=268435456
WARNING: Snappy compression is not enabled
------------------------------------------------
fillseq      :       2.134 micros/op;   51.8 MB/s
fillsync     :      70.722 micros/op;    1.6 MB/s (100000 ops)
fillrandom   :       5.229 micros/op;   21.2 MB/s
overwrite    :       5.396 micros/op;   20.5 MB/s
readrandom   :      65.729 micros/op;
readrandom   :      43.086 micros/op;
readseq      :       0.882 micros/op;  125.4 MB/s
readreverse  :       1.200 micros/op;   92.2 MB/s
compact      : 24599514.008 micros/op;
readrandom   :      12.663 micros/op;
readseq      :       0.372 micros/op;  297.4 MB/s
readreverse  :       0.559 micros/op;  198.0 MB/s
fill100K     :     349.894 micros/op;  272.6 MB/s (10000 ops)
crc32c       :       4.759 micros/op;  820.8 MB/s (4K per op)
snappycomp   :       3.099 micros/op; (snappy failure)
snappyuncomp :       2.146 micros/op; (snappy failure)

#1亿条记录
$sudo ./db_bench --num=100000000 --write_buffer_size=$((256*1024*1024))
LevelDB:    version 1.2
Date:       Fri May 27 17:39:19 2011
CPU:        24 * Intel(R) Xeon(R) CPU           X5670  @ 2.93GHz
CPUCache:   12288 KB
Keys:       16 bytes each
Values:     100 bytes each (50 bytes after compression)
Entries:    100000000
RawSize:    11062.6 MB (estimated)
FileSize:   6294.3 MB (estimated)
write_buffer_size=268435456
WARNING: Snappy compression is not enabled
------------------------------------------------
fillseq      :       2.140 micros/op;   51.7 MB/s
fillsync     :      70.592 micros/op;    1.6 MB/s (1000000 ops)
fillrandom   :       6.033 micros/op;   18.3 MB/s
overwrite    :       7.653 micros/op;   14.5 MB/s
readrandom   :      44.833 micros/op;
readrandom   :      43.963 micros/op;
readseq      :       0.561 micros/op;  197.1 MB/s
readreverse  :       0.809 micros/op;  136.8 MB/s
compact      : 123458261.013 micros/op;
readrandom   :      14.079 micros/op;
readseq      :       0.378 micros/op;  292.5 MB/s
readreverse  :       0.567 micros/op;  195.2 MB/s
fill100K     :    1516.707 micros/op;   62.9 MB/s (100000 ops)
crc32c       :       4.726 micros/op;  826.6 MB/s (4K per op)
snappycomp   :       1.907 micros/op; (snappy failure)
snappyuncomp :       0.954 micros/op; (snappy failure)

#10亿条记录
$sudo ./db_bench --num=1000000000 --write_buffer_size=$((256*1024*1024))
Password:
LevelDB:    version 1.2
Date:       Sun May 29 17:04:14 2011
CPU:        24 * Intel(R) Xeon(R) CPU           X5670  @ 2.93GHz
CPUCache:   12288 KB
Keys:       16 bytes each
Values:     100 bytes each (50 bytes after compression)
Entries:    1000000000
RawSize:    110626.2 MB (estimated)
FileSize:   62942.5 MB (estimated)
write_buffer_size=268435456
WARNING: Snappy compression is not enabled
------------------------------------------------
fillseq      :       2.126 micros/op;   52.0 MB/s
fillsync     :      63.644 micros/op;    1.7 MB/s (10000000 ops)
fillrandom   :      10.267 micros/op;   10.8 MB/s
overwrite    :      14.339 micros/op;    7.7 MB/s
...比较慢待补充

总结: Leveldb是个很好的kv库,重点解决了随机IO性能不好的问题,多线程更新的性能非常好.

玩得开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

相关 [leveldb 性能分析] 推荐:

leveldb性能分析和表现

- Adam - Erlang非业余研究
原创文章,转载请注明: 转载自Erlang非业余研究. 本文链接地址: leveldb性能分析和表现. Leveldb是一个google实现的非常高效的kv数据库,目前的版本1.2能够支持billion级别的数据量了. 在这个数量级别下还有着非常高的性能,主要归功于它的良好的设计. 那么数据库最怕的的随机IO他是如何解决的呢.

[转][转]LevelDB性能分析和表现

- - heiyeluren的Blog
LevelDB是一个Google开发的速度飞快的数据库键值存储引擎,可按照字符串键值顺序映射. 2011年7月30日 Google宣布按照BSD许可 开源LevelDB. LevelDB是一个C++库,可用于很多情况. 比如用于一个网页浏览器存储最近存取网页的缓存,或用于操作系统存储安装包列表,或用于应用存储用户的设置参数.

Google开源LevelDB

- 酿泉 - Solidot
Google宣布在BSD许可证下开源其键值存储引擎LevelDB. LevelDB C++库可用于多种不同环境,如被浏览器用于存储最近访问的网页缓存,或者被操作系统使用去储存安装的软件包和依赖包清单,或被应用程序用于存储用户设置. Google称,即将发布的新版Chrome浏览器,就包含了基于LevelDB的IndexedDB HTML5 API实现.

LevelDB:实现(译)

- 高春辉 - 银河里的星星
  作者:Jeff Dean, Sanjay Ghemawat. 原文:http://leveldb.googlecode.com/svn/trunk/doc/impl.html. 译者:phylips@bmy 2011-8-17. 出处:http://duanple.blog.163.com/blog/static/7097176720112643946178/ .

LevelDB内部实现

- Ben - NoSQLFan
本文是一篇转载的翻译文章,翻译对象是LevelDB的官方文档中实现一章,主要描述了LevelDB内部的数据结构,文件结构及相关的存储,压缩恢复等功能的实现过程,看完后你就能知道,LevelDB为什么会叫这个名字了. 作者:Jeff Dean, Sanjay Ghemawat. 原文:leveldb.googlecode.com.

cpy-leveldb:Python 版的 LevelDB

- Ken - python.cn(jobs, news)
>>> db.Get("2") '222' >>> db.Get("5") '' >>> db.Write(batch) >>> db.Get("5") 'hello world 5' >>> db.Get("2") 'hello world 2' >>> iter = leveldb.Iterator(db) Iterator_init executed.

LevelDB学习交流

- gnawux - NoSQLFan
下面PPT作者是@淘宝解伦,PPT中对LevelDB的特点、设计思想及实现原理都有所涵盖,是一篇不错的LevelDB入门教材. 对LevelDB感兴趣的同学可以看看. LevelDB中的Skip List(跳跃表). 一个NoSQL与MongoDB的介绍PPT. RethinkDB 与 TokuDB 调研测试报告.

LevelDB实现解析

- - NoSQLFan
LevelDB是Google开发的一个key-value存储,其已经作为存储引擎被Riak和Kyoto Tycoon所支持( 这里和 这里),在国内 淘宝的 Tair开源key-value存储也已经将LevelDB作为其持久化存储引擎,并部署在线上使用. 下面PDF就是 淘宝核心系统研发团队的那岩总结的LevelDB内部实现的长文.