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,减少目录的压力。
我的测试环境是:
# 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说:
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倍的提高。
我们来看下实际的性能数字:
$ sudo ./db_bench --num=10000000 --write_buffer_size=$((256*1024*1024)) |
Date: Fri May 27 17:14:33 2011 |
CPU: 24 * Intel(R) Xeon(R) CPU X5670 @ 2.93GHz |
Values: 100 bytes each (50 bytes after compression) |
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) |
$ sudo ./db_bench --num=100000000 --write_buffer_size=$((256*1024*1024)) |
Date: Fri May 27 17:39:19 2011 |
CPU: 24 * Intel(R) Xeon(R) CPU X5670 @ 2.93GHz |
Values: 100 bytes each (50 bytes after compression) |
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) |
$ sudo ./db_bench --num=1000000000 --write_buffer_size=$((256*1024*1024)) |
Date: Sun May 29 17:04:14 2011 |
CPU: 24 * Intel(R) Xeon(R) CPU X5670 @ 2.93GHz |
Values: 100 bytes each (50 bytes after compression) |
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性能不好的问题,多线程更新的性能非常好.
玩得开心!
- 如何进行python性能分析?
在分析python代码性能瓶颈,但又不想修改源代码的时候,ipython shell以及第三方库提供了很多扩展工具,可以不用在代码里面加上统计性能的装饰器,也能很方便直观的分析代码性能.下面以我自己实 ...
- SQL Server-聚焦IN VS EXISTS VS JOIN性能分析(十九)
前言 本节我们开始讲讲这一系列性能比较的终极篇IN VS EXISTS VS JOIN的性能分析,前面系列有人一直在说场景不够,这里我们结合查询索引列.非索引列.查询小表.查询大表来综合分析,简短的内 ...
- SQL Server-聚焦NOT IN VS NOT EXISTS VS LEFT JOIN...IS NULL性能分析(十八)
前言 本节我们来综合比较NOT IN VS NOT EXISTS VS LEFT JOIN...IS NULL的性能,简短的内容,深入的理解,Always to review the basics. ...
- SQL Server-聚焦LEFT JOIN...IS NULL AND NOT EXISTS性能分析(十七)
前言 本节我们来分析LEFT JOIN和NOT EXISTS,简短的内容,深入的理解,Always to review the basics. LEFT JOIN...IS NULL和NOT EXIS ...
- SQL Server-聚焦EXISTS AND IN性能分析(十六)
前言 前面我们学习了NOT EXISTS和NOT IN的比较,当然少不了EXISTS和IN的比较,所以本节我们来学习EXISTS和IN的比较,简短的内容,深入的理解,Always to review ...
- SQL Server-聚焦NOT EXISTS AND NOT IN性能分析(十五)
前言 上一节我们分析了INNER JOIN和IN,对于不同场景其性能是不一样的,本节我们接着分析NOT EXISTS和NOT IN,简短的内容,深入的理解,Always to review the b ...
- SQL Server-聚焦INNER JOIN AND IN性能分析(十四)
前言 本节我们来讲讲联接综合知识,我们在大多教程或理论书上都在讲用哪好,哪个性能不如哪个的性能,但是真正讲到问题的实质却不是太多,所以才有了本系列每一篇的篇幅不是太多,但是肯定是我用心去查找许多资料而 ...
- Java 性能分析工具 , 第 3 部分: Java Mission Control
引言 本文为 Java 性能分析工具系列文章第三篇,这里将介绍如何使用 Java 任务控制器 Java Mission Control 深入分析 Java 应用程序的性能,为程序开发人员在使用 Jav ...
- Java 性能分析工具 , 第 2 部分:Java 内置监控工具
引言 本文为 Java 性能分析工具系列文章第二篇,第一篇:操作系统工具.在本文中将介绍如何使用 Java 内置监控工具更加深入的了解 Java 应用程序和 JVM 本身.在 JDK 中有许多内置的工 ...
随机推荐
- Learning BSD.sys/queue.h
This file includes 4 data-structures.. Insteresting because they are written in 1994.. to make it ea ...
- U盘做svn版本控制
svn提供的访问方式有: file:///本地路径/to/svnrepo/ //访问本地磁盘 http://host/to/svnrepo/ //通过配置subversion的apache服务器的we ...
- Apache+Tomcat服务器集群配置
在实际应用中,如果网站的访问量很大,为了提高访问速度,可以与多个Tomcat服务器与Apache服务器集成,让他们共同运行servlet/jsp 组件的任务,多个Tomcat服务器构成了一个集群(Cl ...
- HDU 3338 Kakuro Extension
网络最大流 TLE了两天的题目.80次Submit才AC,发现是刘汝佳白书的Dinic代码还可以优化.....瞬间无语..... #include<cstdio> #include< ...
- IOS把图片缓存到本地的几种方法
把图片缓存到本地,在很多场景都会用到,如果是只储存文字信息,那建一个plist文件,或者数据库就能很方便的解决问题,但是如果存图片到沙盒就没那么方便了.这里介绍两种保存图片到沙盒的方法. 一.把图片转 ...
- Myeclipse8.6安装freemarker插件
1. 打开http://sourceforge.net/projects/freemarker-ide/files/ 下载最新版本,目前本人下载时最新版本是:freemarker-ide-0.9.14 ...
- SSH登录很慢问题的解决方法
用ssh连其他linux机器,会等待10-30秒才有提示输入密码.严重影响工作效率. 关闭ssh的gssapi认证 用ssh -v user@server 可以看到登录时有如下信息: debug1: ...
- easyui 动态渲染
$.parser.parse 这个 $("div[data-easyuisrc]").html(function () { var url = $(this).attr(&qu ...
- UICollectionView之自定义Layout
#import <UIKit/UIKit.h> @interface WQViewController : UIViewController - (id)initWithFrame:(CG ...
- cscope
http://sourceforge.net/p/cscope/bugs/247/ buffer read only? cx cq Here is a simple patch which re-en ...