MongoDB性能测试(By 小木&&晓擒)

原创 2013年12月06日 09:39:11

测试图片有点多,无法直接插入大量图片,源测试文档链接:http://wenku.baidu.com/view/2b20025727d3240c8447ef8d.html

测试环境


加压机

系统:WindowsXP SP3,32位

内存:4G

CPU:双核/2.2GHz

IO:33M/秒

服务器

系统:centos系统,64位

CPU:4核/2.1GHz(除了进行CPU个数测试的时候)

IO上限:未测得,未达到,未成为限制

各服务器的内存和磁盘大小因需要各不一样


监测工具

Mongostat

1)监测速度

2)监测IO数值

3)监测连接数con

4)监测内存res

5)监测locked

Zabbix

1)监测内存

2)监测CPU情况

3)监测IO数值

4)SWAP

软件版本

服务器MongoDB版本:2.4.8

加压机Java jdk版本:1.7.0_45

MongoDB Java驱动版本:2.9.3

测试用数据结构

词库

词库1:dict,从英语字典里抓取7998个词汇

词库2:color,自己建立,10个词

结构

“_id”

系统生成,12字节,

数字】“numb”

自增的

字符串】“name”

从词库1中随机

长字符串】“describe”

128字节,String,固定的

时间】"time"

ISODate("2013-11-19T08:23:03.468Z")

bool】“flag”

随机,

数值】“price”

20-1020之间随机的随机数

嵌套对象】“parameter”

数值】“size”

0-50之间随机数,

字符串】“logo”

词库1中随机前100

数组】“color”

长度从2-10随机,内容从词库2随机

数组】“category”

长度从2-10随机,内容从词库1随机

图片】“image”

1.04M,名字和numb相同

范例

"_id" : ObjectId("528d6cd5621e8e90e5ae7a7f"),

"number" : 0,

"name" : "mutton",

"describe" : "The most distant way in the world is not the way from birth to the end.

       It is when I sit near you that you don't understand I love you.

       The most distant way in the world is not that you're not sure I love you.

      It is when my love is bewildering the soul, but I can't speak it out.",

"time" : ISODate("2013-11-21T02:15:49.093Z"),

"flag" : 0,

"price" : 975,

"parameter" : {

       "size" : 1,

       "logo" : "accelerate",

       "color" : [

              "black", "yellow", "black", "blue", "pink", "indigo", "red",

              ]

       },

"category" : [

       "fascination", "credit", "comparison", "island", "grandfather"

       ]

 

测试

i1、不同索引对于插入性能的影响

测试描述:

4g内存,单线程,单索引,从0插入20万条数据

测试数据


横坐标:数据类型    纵坐标:插入时间(毫秒)

猜测

1、数组列耗时较长的可能原因:数组内字段比较多,同时每个元素的变化范围也比较大。

2、可能每个索引的建立对于性能的影响主要从三个方面:一个是该列数据的分布范围(比如,从1万中可能中变化的要慢于从10个可能中变化的),另外就是该列数据包含的数据数量(数组就明显慢于字符串),另数字和时间比较快可能和这两列的值是比较有规律的有关。

结论

建立索引后,插入性能有明显下降,但是,不同数据类型的索引对于插入性能影响不大。

i2、1亿级别数据无索引插入性能测试

测试描述:

单线程插入1亿条数据,插入前数据库无索引、无数据。

测试数据

 



横坐标:时间(秒)      纵坐标:插入速度(个/秒)

横坐标:时间(秒)             纵坐标:内存占用量(MB)(4G)

横坐标:时间(秒)             纵坐标:总数据量(个数)

结论:

无索引状态下,内存状态(装满与否)对于插入速度没有影响,插入速度宏观上稳定,有明显震荡。

i3、5000万级别数据全索引插入性能测试

测试描述:

单线程插入5000万条数据, 插入前建立全索引(number, name, time, flag, price, parameter. size, parameter. logo, parameter. color, category),无数据, 原计划插入1亿,后因速度太慢,时间太长终止于五千万。

测试数据




横坐标:时间(秒)             纵坐标:插入速度(个/秒)

横坐标:时间(秒)             纵坐标:内存占用量(MB)(4G)

横坐标:时间(秒)             纵坐标:总数据量(个数)

结论

有索引的状态下,内存状态(装满与否)对于插入速度有影响,但是影响不大;插入速度随着数据量的增加而缓慢下降,震荡一直存在。

i4、2亿数据双索引插入(1亿基础上)性能测试

测试描述:

在1亿数据基础上单线程插入2亿条数据,有 双索引:number、name ,内存10g

测试数据




横坐标:时间(秒)             纵坐标:插入速度(个/秒)

横坐标:时间(秒)             纵坐标:内存占用量(MB)(4G)

横坐标:时间(秒)             纵坐标:插入速度(个/秒)(前750)

结论

插入速度和内存状态无关,随着数据量的增多,插入速度有下降的趋势,但是幅度很小;插入性能需要一段时间,才能提高到比较稳定的范围,震荡一直存在。

i5、2亿数据双索引插入(3亿基础上)性能测试

测试描述:

在3亿数据基础上单线程插入2亿条数据,有 双索引:number、name ,内存10g

测试数据

横坐标:时间(秒)             纵坐标:插入速度(个/秒)


横坐标:时间(秒)             纵坐标:插入速度(个/秒)(前1000)

结论

和1亿数据基础上的插入非常类似,速度略有下降, 开始的提升过程需要更长的时间。

i6、Shard插入性能测试

测试描述:

单线程,在1亿基础上插入1000万条数据,无索引,双服务器shard。

测试数据


横坐标:时间(秒)             纵坐标:插入速度(个/秒)

结论

速度很快,和单服务器的插入性能在同样的水平(>11K/s)。

震荡原因分析:

在使用Sharding的时候,Mongodb会对数据拆分搬迁,这个时候性能下降很厉害, 但是我在实际观察中可以发现,在搬迁数据的时候每秒插入性能可能会下降一半。

其实我觉得能手动切分数据库就手动切分或者手动做历史库,不要依赖这种自动化的Sharding,因为一开始数据就放到正确的位置比分隔再搬迁效率不知道高多少。

i7、五组大数据量插入性能对比

测试描述:

全部都是单线程插入,数据结构都是相同的,左1是shard(双) ,其他都是单服务器

测试数据


横坐标:(X-Y-Z)  纵坐标:插入速度(个/秒)

X:插入的数据量 ;Y:数据库中已有数据量 ;Z:索引个数

结论

索引数的增加会降低插入的性能,数据库中的总数据量增加也会降低插入性能,但是影响不大, Shard的搭建会降低插入性能。

i8、不同数据量占用磁盘空间大小对比

测试描述:

数据库中插入响应大小数据后,占用的磁盘空间大小,索引都只有三个:_id,number ,name

测试数据


横坐标:数据量-总体              纵坐标:占用磁盘大小(GB)


 

横坐标:数据量-索引              纵坐标:占用磁盘大小(GB)

 

 

结论

磁盘和索引占用的空间基本都随着数据量的增加而线性增长。

i9、GridFS和二进制插入性能对比

测试描述:

单线程插入1000条, 数据字段id, number, image。

测试数据

注:指数坐标     横坐标:图片大小     纵坐标:插入耗时(毫秒)

进制插入的java代码-范例

File ima = new File("436k.jpg");
FileInputStream fileIps = new FileInputStream(ima);
ByteArrayOutputStream bao = new ByteArrayOutputStream();
int imalength;
while ((imalength = fileIps.read()) != -1){
	bao.write(imalength);}
fileIps.close();
byte[] imabyte = bao.toByteArray();
bao.close();
document.put("imagByte",imabyte); 

结论

无论图片大小,GridFS存图片比二进制存储效率高一个数量级。

Java的二进制存入代码可能有问题,单跑put之上的代码也要消耗同样多的时间。

q1、针对不同数据类型查询的性能差别

测试描述:

五千万数据,全索引,单线程,数字列是查询0-100万随机,其他类型全口径随机,但只返回一条数据。

测试数据


横坐标:数据类型            纵坐标:查询速度(个/秒)

结论

针对不同数据类型的查询,性能差别不大。

可以在大数据情况下只测试查询某一个数据项而能够代表其查询性能。

q2、并发数不同对于查询性能的影响

测试描述:

五千万数据,全索引,随机查询前100万数据

测试数据


线程数1-900     横坐标:线程数         纵坐标:查询速度(个/秒)


 

线程数1-30 横坐标:线程数         纵坐标:查询速度(个/秒)

结论

MongoDB服务器的总体查询性能,随着并发数的增加,呈现某种类似抛物线的特点,过了最高点后会随着并发数增加而开始缓慢下降。

注:最大并发数1013,在并发数达到900以后开始偶尔出现连接不上的问题。

单线程查询速度比较慢的原因可能和脚本的性能有关。

q3、Limit对于查询性能的影响

测试描述:

五千万数据,全索引,单线程,查询10万次,随机查询name,limit(x)

测试数据

 

横坐标:limit(x)的X值          纵坐标:查询速度(个/秒)

结论

limit值递增,每次查询的返回数据量递增,速度也随之下降。

q4、skip对于查询性能的影响

测试描述:

五千万数据,全索引,单线程,查询10万次,随机查询name,skip(x).limit(10)

测试数据

 

横坐标:skip(x).limit(10)的X值         纵坐标:查询速度(个/秒)

结论

skip值递增,速度也随之下降,但是在100以内下降不明显。

q5、1亿数据随机全查性能测试

测试描述:

1亿数据,双索引number,name,20线程,10g内存,随机全查全部number,即热数据 = 1亿条,远大于内存容量。截取数据为mongostat

测试数据


横坐标:时间(秒)             纵坐标:查询速度(个/秒)

Zabbix监测数据


CPU利用率很低(后半段是该次测试的数据)


SWAP使用频繁(后半段是该次测试的数据)


内存长时间被吃满

结论

在热数据大幅度超过内存可容纳的量时,查询速度骤降到低位,并小幅度震荡。

q6、1亿数据随机查前1000万性能测试

测试描述:

1亿数据,双索引number,name,20线程,10g内存,随机全查全部number,即热数据 = 千万条,小于内存容量。截取数据为mongostat

 

测试数据


 

横坐标:时间(秒)             纵坐标:查询速度(个/秒)

Zabbix监测数据


CPU使用率处于高位


内存吃满


SWAP使用率很低


I/O处于高位

结论

在热数据可全部装入内存时,查询速度在高位小幅度震荡。

q7、热数据量大小(<内存大小)对于查询性能的影响

测试描述:

五千万数据,全索引,20线程,4G内存,随机查询前X万数据,查询截取faults长时间稳定为0的情况,即:热数据全部装入内存。

测试数据


横坐标:热数据量            纵坐标:查询速度(个/秒)

结论

热数据量增加,查询性能缓慢下降。 另:热数据量增加到内存无法装下时,性能骤降2个数量级。

q8、热数据进入内存过程对于查询性能的影响

测试描述:

五千万数据,全索引, 4G内,20线程,随机查询前450万数据

测试数据


横坐标:时间(秒)             纵坐标:查询速度(个/秒)


 

横坐标:时间(秒)             纵坐标:mongostat-faults数量(查询未命中数量)

结论

随着热数据逐步进入内存,查询速度缓慢上升,在热数据全部进入内存后,Faults下降到0,查询速度迅速攀升到峰值,并稳定维持.

注:热数据进入内存的时间,可能不是线性的.即1000万热数据进入内存的时间可能远超过100万热数据进入内存的时间的10倍。

q9、1-3-5亿数据量查询前1000万性能对比

测试描述:

10G内存,20线程,随机查询前1000万数据(热数据全部能进入内存),Faults长时间稳定为0后截取数据。

测试数据


横坐标:时间(秒)             纵坐标:查询速度(个/秒)

结论

相同热数据量(<内存),查询性能随着总数据量的增加而下降。

注:只截取了40个点,所以观测的震荡比较明显,长时间的数据总体是稳定的。

q10、1-3-5亿数据量查询前1亿性能对比

测试描述:

10G内存(热数据量远大于内存容量),20线程,随机查询前1亿数据 ,内存res基本稳定后截取数据。

测试数据


横坐标:时间(秒)             纵坐标:查询速度(个/秒)

 


横坐标:时间(秒)             纵坐标:mongostat-faults数量(查询未命中数量)

结论

热数据量增加到远大于内存后,总数据量增加还是会降低查询速度,但是影响非常不明显,震荡比例也变得剧烈。

Faults和查询速度基本上同步

q11、1-3-5亿数据不同热数据量查询性能对比

测试描述:

双索引,10g内存,20线程,随机查询number

测试数据

 

横坐标:5亿数据中随机查询前X条数据          纵坐标:查询速度(个/秒)

 

横坐标:X数据中随机查询前1000万        纵坐标:查询速度(个/秒)

 

横坐标:X数据中随机查询前1亿              纵坐标:查询速度(个/秒)

 

横坐标:X数据中随机查询前2亿              纵坐标:查询速度(个/秒)

结论

总数据量和热数据量的大小都会对查询速度产生影响, 热数据量能否全部进入内存对于性能影响巨大,差两个数量级,总数据量的增加和超过内存大小的热数据量的增加对于查询性能的影响不大。

q12、5亿数据量查询不同数据量性能对比

测试描述:

10G内存,20线程,5亿数据量,随机查询不同数据量,内存res基本稳定后截取数据

测试数据


横坐标:时间(秒)             纵坐标:查询速度(个/秒)


热数据量大于内存部分详细:横坐标:时间(秒)              纵坐标:查询速度(个/秒)

结论

热数据能否全部装入内存对于查询速度影响巨大。热数据量超过内存大小时,热数据量的增加会降低查询性能,但影响变得很小。

q13、Shard(双机) 查询性能测试

测试描述:

1亿数据量,单索引number

测试数据

 

20线程:     横坐标:热数据量     纵坐标:查询速度(个/秒)

 

 

横坐标:线程数         纵坐标:查询速度(个/秒)


横坐标:时间             纵坐标:查询速度(个/秒)

结论

查询的最快速度在8,000附近,相比单服务器(2.3万)的查询速度有明显的下降,其他方面的性能和单服务器的查询性能类似。 震荡很有周期性。

q14、Shard(双机) 和单服务器的查询性能对比

测试描述:

20线程,随机查询number,Shard: 1亿数据,单服务器: 5千万数据。

测试数据


横坐标:热数据量            纵坐标:查询速度(个/秒)

结论

Shard查询速度相比单服务器明显下降。  

q15、CPU与查询性能的关系

测试描述:


5亿数据,20线程,查询前100万 。

测试数据



横坐标:CPU数量    纵坐标:查询速度(个/秒)


横坐标:加压机数量 纵坐标:查询速度(个/秒)

结论

查询性能随着CPU数量的增加而线性增加。

另:

4核之前,速度随着CPU的增加线性增加,8核降低由于加压机功率不够。

8核,“单”的限制条件加压机的CPU达到上限。

o1、不同情况建立索引的对比

现象描述:

CPU爆满、内存吃满、locked锁死

索引项

情况

耗时

Price

单服务器、1亿数据、10g内存

约54分钟

Price

单服务器、3亿数据、10g内存

约5小时

number

Shard-双机、1亿数据、4g内存

约19分钟

结论

建立索引的时间随着数据量的增加呈现快速增长,而且在建立索引时,服务器什么都做不了,完全锁死 。

注:如果在大数据量上建立索引,要有足够的时间

o2、repairDatabase的现象

象描述

repairDatabase执行3小时左右,期间CPU爆满、内存吃满、locked锁死

操作描述

数据库大小

插入1亿无索引数据

69G

插入1千万数据后

79G

把这1千万数据删除

79G

执行repairDatabase

71G

结论

数据库空间会动态增长但是不会动态减少,

MongoDB分配空间的原则是不够用就动态增加一个数据块, 数据块的大小最开始是16M,然后32M,然后64M,依此翻倍增加到2G以后,数据库大小不再增加,每次都是分配2G大小的数据块。

测试结论

插入

1       内存状态(装满与否)对于插入速度没有影响

2       插入速度随着数据量的增加而缓慢下降

3       批量插入的过程中震荡一直存在,且幅度较大

4       有索引的批量插入在开始时插入速度有一个从慢到快的过程,这一过程随着数据量的增加而逐渐延长

5       索引的建立会明显降低插入速度,索引数越多插入速度越慢

6       磁盘和索引占用的磁盘空间基本都随着数据量的增加而线性增长

7       无论图片大小,GridFS存图片比二进制存储效率高

查询

8       针对不同数据类型的查询,性能几乎没有差别

9       线程数20之前,查询性能随线程数增加线性增加,在线程数超过100后,查询性能随着线程数增加缓慢下降,在1013开始报错

10    limit值递增,每次查询的返回数据量递增,速度也随之下降

11    skip值递增,速度也随之下降,但是在100以内下降不明显

12    热数据全部装入内存时,查询速度在高位小幅度震荡

13    热数据量超过内存大小时,查询速度骤降两个数量级

14    查询性能随着热数据量(大于或者小于内存的两侧)的增加而缓慢下降

15    查询性能随着总数据量的增加而缓慢下降

16    Shard查询速度相比单服务器明显下降

17    查询性能随着CPU数量的增加而线性增加

没有解决的问题

1.     连接数问题,con无法突破1013

2.     locked比例过高问题(建索引,批量插入等行为)

3.     内存大小和理想热数据量的函数关系

4.     GridFS存储的具体机制

5.     性能震荡

6.     不同语言驱动性能不同

7.     索引数量与插入速度的函数关系

8.     安全插入相关性能测试

9.     排序、$gte、$lte的性能

10.  【错误1067 】MongoDB异常关闭,无法正常启动,需删除lock文件

11.  Mongostat的内存res和Zabbix的内存不一致

 

相关文章推荐

MongoDB简单测试

pom.xml添加: org.mongodb mongo-java-driver 3.0.2 import java.util.ArrayList; im...
  • sunhuwh
  • sunhuwh
  • 2015年06月07日 23:48
  • 7382

Mongodb亿级数据量的性能测试

进行了一下Mongodb亿级数据量的性能测试,分别测试如下几个项目: (所有插入都是单线程进行,所有读取都是多线程进行) 1) 普通插入性能 (插入的数据每条大约在1KB左右) 2) 批量插...
  • zrjdds
  • zrjdds
  • 2016年08月09日 09:48
  • 1221

【MongoDB】MongoDB之八大优化技巧

技巧一、尽量减少磁盘访问 内存访问要比磁盘访问快得多。所以使用优化的本质就是尽可能地减少对磁盘的访问。  内存的读取速度要比磁盘速度快一百万倍。读磁盘要消耗很长时间。几种简单的办法: 使...

MongoDB性能测试报告

  • 2014年03月24日 10:34
  • 1.64MB
  • 下载

loadrunner性能测试错误:Abnormal termination, caused by mdrv process termination

loadrunner性能测试错误:Abnormal termination, caused by mdrv process termination 原文地址:http://m.oschina.n...

MongoDB、HandlerSocket和MySQL性能测试及其结果分析

原文地址:http://www.cnblogs.com/inrie/archive/2011/02/22/1961415.html 一、测试环境1、测试服务器状况共涉及4台测试服务器:压力测试服务器W...

node.js mongodb数据库驱动性能测试

众所周知,node.js的特点是单线程、事件驱动、异步IO,适合开发运行在分布式设备上的实时性较强的数据密集型应用。今天做了一个性能测试,相同的场景下,拿java和node对比测试,数据库是mongo...
  • shmnh
  • shmnh
  • 2015年02月02日 08:10
  • 1250

性能测试工具操作数据库(五)-Jmeter与MongoDB

JMeter测试MongoDB性能有两种方式,一种是利用JMeter直接进行测试MongoDB,还有一种是写Java代码方式测试MongoDB性能。...

Mongodb亿级数据量的性能测试

Mongodb亿级数据量的性能测试  进行了一下Mongodb亿级数据量的性能测试,分别测试如下几个项目:   (所有插入都是单线程进行,所有读取都是多线程进行) 1) 普通插入性能 (插入...

mongodb3.0 性能测试报告 一

对刚刚发布的mongodb3.0 进行测试。 分为单机单插入,单机混合操作,分片混合 三个场景的测试,这是第一个。...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MongoDB性能测试(By 小木&&晓擒)
举报原因:
原因补充:

(最多只允许输入30个字)