使用YCSB测试MongoDB的微分片性能
微分片的定义就是使用MongoDB的分片技术,但是多个或者全部分片Mongod运行在同一台服务器(服务器可以是物理机或者虚机)上。由于
MongoDB的库级锁
MongoDB是目前最流行的NoSQL数据库,以其自然的文档型数据结构,灵活的数据模式以及简单易用的水平扩展能力而获得了很多开发人员的青睐。 但是金无足赤人无完人,MongoDB不是没有它的一些弱点,,比如说它的库级锁就是人们经常抱怨的一个性能瓶颈。简单来说MongoDB的库级锁就是针对某一个数据库的所有写操作,必须在获得这个数据库仅有的一个互斥锁情况下才能进行。这个听上去很糟糕,但实际上由于一个写操作只是针对于内存数据更新的那一刹那保留锁,所以每个写锁的占用时间通常是在纳秒级别。正因为如此,实际应用中库级锁并没有对性能产生人们所担忧的那样显著的影响。
在少数超高并发写的应用场景下,库级锁会可能是一个瓶颈。这个可以通过MongoDB的MMS监控里面的DB Lock %(或者mongostat的命令行输出)指标来进行观察。一般情况下如果DB Lock %超过70-80%并持续就可以认为已经到饱和状态了。如何解决这个问题呢?
方案一: 分片
这个是MongoDB的标准答案如果你有足够的硬件资源。 分片是解决大部分性能瓶颈问题的终极方式。
方案二:分库
这是个非常有效的变通手段。具体做法就是把你的数据分到几个不同的数据库里,然后在应用程序里的数据访问层实现一个路由切换,保证数据读写会被指向到相应的数据库里。一个比较好的例子在一个人口普查的数据库里,你可以为每个省建一个单独的库。31个数据库组成一个逻辑大库。但是这种做法不是什么时候都能用的,比如说如果你需要很多整库数据的查询排序那样的操作,那么协调多个库的结果就会显得很麻烦或者无法实现。
方案三:等待
MongoDB 2.8 即将发布。2.8的最大改动就是把库级锁改成了文档级锁。由库级锁引起的性能问题应该有望得到较大改善。
方案四:微分片
微分片的定义就是使用MongoDB的分片技术,但是多个或者全部分片Mongod运行在同一台服务器(服务器可以是物理机或者虚机)上。由于库级锁的存在,以及MongoDB对多核CPU的利用率不是很高的特性,微分片在满足以下条件的场景下会是一个不错的性能调优手段:
1) 服务器有多核(4或8或更多)CPU
2) 服务器尚未出现IO瓶颈
3) 有足够内存装下热数据(没有出现频繁的 page faults)
在这篇文章里我们通过做一些性能测试来看一下使用微分片技术以后对性能提升的影响。
YCSB 性能测试工具
在开始测试之前,我想首先花点时间介绍一下YCSB这个工具。原因是很多时候我看到开发工程师或者DBA们做测试的时候往往会用一些非常简单的工具作为客户端进行高并发的插入或读取测试。MongoDB本身是一个高性能的数据库,并发量在适当调优的情况下可以达到每秒数万级。如果客户端的代码是简单粗暴型的,甚至使用单线程的客户端,那么性能测试的瓶颈首先就是在客户端本身,而不是服务器。所以选择一个高效的客户端是一个好的性能测试的重要的第一步。
YCSB是Yahoo开发的一个专门用来对新一代数据库进行基准测试的工具。全名是Yahoo! Cloud Serving Benchmark。 他们开发这个工具的目的是希望有一个标准的工具用来衡量不同数据库的性能。YCSB做了很多优化来提高客户端性能,例如在数据类型上用了最原始的比特数组以减少数据对象本身创建转换所需的时间等。YCSB的几大特性:
* 支持常见的数据库读写操作,如插入,修改,删除及读取
* 多线程支持。YCSB用Java实现,有很好的多线程支持。
* 灵活定义场景文件。可以通过参数灵活的指定测试场景,如100%插入, 50%读50%写等等
* 数据请求分布方式:支持随机,zipfian(只有小部分的数据得到大部分的访问请求)以及最新数据几种请求分布方式
* 可扩展性:可以通过扩展Workload的方式来修改或者扩展YCSB的功能
安装YCSB
由于YCSB本身会承担很大的工作量,一般建议部署YCSB在单独的机器上,最好是4-8核CPU,8G内存以上。YCSB和数据库服务器最少要保证千兆的带宽,最好是万兆级。
* 安装JDK 1.7
* 下载实现了MongoDB驱动的YCSB编译版:
资源包下载地址:
------------------------------------------分割线------------------------------------------
FTP地址:ftp://ftp1.linuxidc.com
用户名:ftp1.linuxidc.com
密码:
在 2015年LinuxIDC.com\7月\使用YCSB测试MongoDB的微分片性能
下载方法见
------------------------------------------分割线------------------------------------------
* 解压缩
* 进入到ycsb目录并运行(本地要有一个Mongo数据库在 27017端口上):
./bin/ycsb run mongodb -P workloads/workloada
* 如果YCSB可以运行则表明安装成功
你也可以用Git把源文件拉下来自己编译。需要JDK和Maven工具。Github地址是:https://github.com/achille/YCSB 可以参考这个页面进行编译安装YCSB: https://github.com/achille/YCSB/tree/master/mongodb
YCSB场景文件
使用YCSB测试不同场景只需要提供不同的场景文件就可以。YCSB会按照你的场景文件的属性而自动生成响应的客户端请求。在我们这次测试里我们会使用到几种场景:
场景S1: 100%插入。用来加载测试数据
场景S2: 写多读少 90% 更新 10%读
场景S3: 混合读写 65%读, 25% 插入, 10% 更新
场景S4: 读多写少 90% 读, 10% 插入、更新
场景S5: 100%读
如下是其中场景文件S2的内容:
recordcount=5000000
operationcount=100000000
workload=com.yahoo.ycsb.workloads.CoreWorkload
readallfields=true
readproportion=0.1
updateproportion=0.9
scanproportion=0
insertproportion=0
requestdistribution=uniform
insertorder=hashed
fieldlength=250
fieldcount=8
mongodb.url=mongodb://192.168.1.2:27017
mongodb.writeConcern=acknowledged
threadcount=32
一些说明:
* 测试数据包括500万个文档(recordcount)
* 每个文档大小大约2KB(fieldlength x fieldcount)。数据总共大小是10G+600M的索引
* MongoDB数据库的url是192.168.1.2:27017
* MongoDB的写安全设置(mongodb.writeConcern)是acknowledged
* 线程数是32(threadcount)
* 插入文档的顺序:哈希/随机 (insertorder)
* 更新操作: 90% (0.9)
* 读操作: 10% (0.1)
下载所有场景文件(S1 – S5)(见上面的Linux公社下载地址) 并解压到上面创建的ycsb目录下面:
MongoDB配置