Mongodb 十亿级数据量的性能测试报告

Mongodb 十亿级数据量的性能测试报告

1、测试环境

1.1 硬件环境

1.1.1 处理器

型号:Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10Ghz

主频:2.1Ghz

核心:4(处理器)

1.1.2 磁盘

型号:LSI MRSASRoMB-8i SCSI Disk Device

容量: 2T

1.2.3 内存

容量:32G

1.2 操作系统以及文件系统

操作系统使用 Redhat Sever6.4-X86-64。

文件系统使用EXT4。

1.3 Mongodb版本

Mongodb 2.6.5-X86-64

1.4 Mongodb数据量

数据行数:10亿行。

存储大小:219.847GB

数据文件存储方式:第一个文件65M,第二个文件129M,第三个文件257M,第四个文件512M,第五个文件1.1GB,其后均为2.0GB。

数据格式:共四列,第一列为状态量ID(1-5000) ,第二列为状态值(0-150),第三列为状态量产生时间(20090101开始),第四列为插入数据库的时间戳。

1.5 测试客户端技术

       1、并发与插入测试:在进行插入性能测试时考虑到并发情况与插入情况,采用Mongodb的Nodejs客户端进行并发插入性能测试。

       2、查询性能测试:在进行查询性能测试时使用Mongodb的Explain语句进行执行计划的查询,该语句类似于Oracle的Autotrace功能。

       为测试Mongodb在亿级数据的实时查询性能,以“Jsp+Servlet+Jquery+D3Js”做了一个实时查询的功能,该功能每秒刷新一次页面实时展示从Mongodb中查询到的数据。

2、测试内容:

2.1 插入性能测试

       测试插入性能时,考虑到可能要在建立索引之后进行插入操作,所以插入性能测试分为“索引建立之前”与“索引建立之后”的查询操作。

       考虑到单进程与并发进程的情况,分为“单进程插入测试”与“10并发插入测试”。

       关于索引的创建,以下有两点说明。

       第一,只以查询字段创建单索引。

       第二,在创建索引时,测试表已有约5亿数据量。

2.2 查询性能测试

       测试查询性能时,需要考虑到索引建立前后查询性能的差别,以及返回数据量对响应时间的影响,判断它们之间是否有一定的关系,所以测试条目以返回的数据量分“单条数据”、“万级数据”、“百万级数据”和“千万级数据”。

       在测试万级以上的返回时间时,只测试索引建立之后的情况,因为影响时间实在太长,等不得。

       在测试查询性能时要考虑到聚合查询的情况,聚合查询以数据量分“万级数据”、“百万级”和“千万级”,只以一个字段为聚合条件,并且只做“Count”运算,在Mongodb中做聚合操作使用类似以下语句:

db.runCommand(

 {

  "group":

  {

    "ns":"visonLog",

    "key":{"value":true},

    "initial":{"count":0},

    "$reduce":function(doc,prev)

    {

      prev.count++;

    },

              "condition":{"time":{"$gt":"20090101130101000",

                                                       "$lt":"20090101140101000"}}

  }

 }

);

3、测试结果

3.1 插入性能

插入性能统计表格1

统计项目

单进程插入(索引建立前)

单进程插入(索引建立之后)

统计结果

656/s - 746/s

534/s - 712/s

插入性能统计表格2

统计项目

10进程并发插入(索引建立前)

10进程并发插入(索引建立之后)

统计结果

3817/s - 3964/s

3306/s - 3389/s

3.2 查询性能

查询性能统计表格1

统计项目

单条数据响应时间(索引建立之前)

单条数据响应时间(索引建立之后)

统计结果

1268904/ms

15/ms

查询性能统计表格2

统计项目

返回万级数据

返回百万级数据

返回千万级数据

统计结果

20/ms

8868/ms

217755/ms

查询性能统计表格3

统计项目

万级数据聚合

百万级数据聚合

返回千万级数据

统计结果

9329/ms

542756/ms

1899415/ms

4、其它

在测试中观察到几个情况,这些情况有好有坏:

第一,在创建索引时,其它的操作如“showcollections”、“db.table.find()”等操作均处于等待状态

第二,内存占用量大当前库的大小达到内存大小(测试环境是32G)时,内存占用达到95%。查资料得知Mongodb在分配内存时是把整个库文件映射到内存中,那就意味着Mongodb在多数的情况下会内存用尽,在该情况下Mongodb的插入性能将会受到影响。

第三,索引建立时间过长,在该测试环境下5亿数据大约用时1.5小时。这个时间远长于Oracle的时间。

第四,Mongodb在达到亿级之后,查询性能与数据总量的大小看不出太大的区别,从这个意义上来讲,Mongodb对大数据量的查询是较好的选择。

第五,Mongodb的存储是以多个文件

5、结论

       一、并发插入性能:

    从插入性能的测试数据来看, 插入性能在索引建立前后并没有大幅度的落差 , 索引建立之后依然可以达到600-700的插入速度。

       在并发的情况下,可以看到性能的下降,每秒少插入大约500条数据,但是插入速度比较稳定,未有太大的幅度。

   二、查询性能:

       建立索引之后,查询速度卓越,从5亿数据中返回万级数据响应速度也可以达到几十毫秒,那么1秒刷新一次也是可以的。

       但mongodb不适合聚合操作,上例中查询出1万条数据以一个字段做聚合,时间是9秒,100万数据用时达到将近10分钟,以我个人使用Oracle的经验来说,这个性能是要低于Oracle的。

   三、最终总结:

       Mongodb适合做实时监控数据,在5亿条数据中返回1万条数据只用几十毫秒,实时监控时就可以把每秒的监控数据返回到前台,达到1秒刷新一次页面的目的。

       但是Mongodb不适合做数据仓库,并且对于聚合操作较多的统计分析场景也不适用,甚至对Mongodb数据库的ETL操作也要精心设计它的数据才能被纳入数据仓库中。

       并且Mongodb的内存管理使用了“内存映射存储引擎”,简单说来就是把库文件整个的映射到内存中,那就意味着如果文件大于内存的话,服务器的内存将几乎全部被占用掉,这个问题几乎没有本质的解决办法,所以使用时一定要考虑使用场景。

你可能感兴趣的:(mongodb)