Leveldb是一个google实现的非常高效的kv数据库,目前的版本1.2能够支持billion级别的数据量了。 在这个数量级别下还有着非常高的性能,主要归功于它的良好的设计。特别是LSM算法。
那么数据库最怕的的随机IO他是如何解决的呢?
先说随机写,它的写都是先记录到日志文件去的,在日志文件满之前只是简单的更新memtable,那么就把随机写转化成了顺序写。在日志满了后,把日志里面的数据排序写成sst表同时和之前的sst进行合并,这个动作也是顺序读和写。大家都知道传统磁盘raid的顺序读写吞吐量是很大的,100M左右是没有问题。在写日志文件的时候,用到是buffer IO,也就是说如果操作系统有足够的内存,这个读写全部由操作系统缓冲,效果非常好。即使是sync写模式,也是以数据累计到4K为一个单位写的,所以效率高。
那么随机读呢?这个它解决不了。但是ssd盘最擅长随机读了。这个硬件很自然的解决了这个问题。
所以leveldb的绝配是ssd盘的raid.
leveldb标准版本编译见浅谈LevelDB在ubuntu 11.04下编译失败的问题,由于标准版本用到了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:23staticconstintkTargetFileSize=32*1048576;
让默认的文件变成32M,减少目录的压力。
我的测试环境是:
$uname-r 2.6.18-164.el5#RHEL5U4 #10*SAS300Graid卡,fusionIO320G,Flashcache,内存96G,24*Intel(R)Xeon(R)CPU
top说:
21782root1801273m1.1g2012R85.31.21152:34db_bench
iostat说:
$iostat-dx5 ... sdb10.400.003.400.0030.400.008.940.024.654.651.58 fioa0.000.002074.803.8016598.4030.408.000.000.130.000.00 dm-00.000.001600.000.0016630.400.0010.390.250.150.1524.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:version1.2 Date:FriMay2717:14:332011 CPU:24*Intel(R)Xeon(R)CPUX5670@2.93GHz CPUCache:12288KB Keys:16byteseach Values:100byteseach(50bytesaftercompression) Entries:10000000 RawSize:1106.3MB(estimated) FileSize:629.4MB(estimated) write_buffer_size=268435456 WARNING:Snappycompressionisnotenabled ------------------------------------------------ fillseq:2.134micros/op;51.8MB/s fillsync:70.722micros/op;1.6MB/s(100000ops) fillrandom:5.229micros/op;21.2MB/s overwrite:5.396micros/op;20.5MB/s readrandom:65.729micros/op; readrandom:43.086micros/op; readseq:0.882micros/op;125.4MB/s readreverse:1.200micros/op;92.2MB/s compact:24599514.008micros/op; readrandom:12.663micros/op; readseq:0.372micros/op;297.4MB/s readreverse:0.559micros/op;198.0MB/s fill100K:349.894micros/op;272.6MB/s(10000ops) crc32c:4.759micros/op;820.8MB/s(4Kperop) snappycomp:3.099micros/op;(snappyfailure) snappyuncomp:2.146micros/op;(snappyfailure) #1亿条记录 $sudo./db_bench--num=100000000--write_buffer_size=$((256*1024*1024)) LevelDB:version1.2 Date:FriMay2717:39:192011 CPU:24*Intel(R)Xeon(R)CPUX5670@2.93GHz CPUCache:12288KB Keys:16byteseach Values:100byteseach(50bytesaftercompression) Entries:100000000 RawSize:11062.6MB(estimated) FileSize:6294.3MB(estimated) write_buffer_size=268435456 WARNING:Snappycompressionisnotenabled ------------------------------------------------ fillseq:2.140micros/op;51.7MB/s fillsync:70.592micros/op;1.6MB/s(1000000ops) fillrandom:6.033micros/op;18.3MB/s overwrite:7.653micros/op;14.5MB/s readrandom:44.833micros/op; readrandom:43.963micros/op; readseq:0.561micros/op;197.1MB/s readreverse:0.809micros/op;136.8MB/s compact:123458261.013micros/op; readrandom:14.079micros/op; readseq:0.378micros/op;292.5MB/s readreverse:0.567micros/op;195.2MB/s fill100K:1516.707micros/op;62.9MB/s(100000ops) crc32c:4.726micros/op;826.6MB/s(4Kperop) snappycomp:1.907micros/op;(snappyfailure) snappyuncomp:0.954micros/op;(snappyfailure) #10亿条记录 $sudo./db_bench--num=1000000000--write_buffer_size=$((256*1024*1024)) Password: LevelDB:version1.2 Date:SunMay2917:04:142011 CPU:24*Intel(R)Xeon(R)CPUX5670@2.93GHz CPUCache:12288KB Keys:16byteseach Values:100byteseach(50bytesaftercompression) Entries:1000000000 RawSize:110626.2MB(estimated) FileSize:62942.5MB(estimated) write_buffer_size=268435456 WARNING:Snappycompressionisnotenabled ------------------------------------------------ fillseq:2.126micros/op;52.0MB/s fillsync:63.644micros/op;1.7MB/s(10000000ops) fillrandom:10.267micros/op;10.8MB/s overwrite:14.339micros/op;7.7MB/s ...比较慢待补充
总结: Leveldb是个很好的kv库,重点解决了随机IO性能不好的问题,多线程更新的性能非常好.
原文链接:http://blog.yufeng.info/archives/1327
【编辑推荐】
- LevelDB—一个超高性能的K/V数据库浅谈LevelDB在ubuntu 11.04下编译失败的问题