Mongodb亿级数据量的性能测试

进行了一下Mongodb亿级数据量的性能测试,分别测试如下几个项目:

 (所有插入都是单线程进行,所有读取都是多线程进行)

1) 普通插入性能 (插入的数据每条大约在1KB左右)

2) 批量插入性能 (使用的是官方C#客户端的InsertBatch),这个测的是批量插入性能能有多少提高

3) 安全插入功能 (确保插入成功,使用的是SafeMode.True开关),这个测的是安全插入性能会差多少

4) 查询一个索引后的数字列,返回10条记录(也就是10KB)的性能,这个测的是索引查询的性能

5) 查询两个索引后的数字列,返回10条记录(每条记录只返回20字节左右的2个小字段)的性能,这个测的是返回小数据量以及多一个查询条件对性能的影响

6) 查询一个索引后的数字列,按照另一个索引的日期字段排序(索引建立的时候是倒序,排序也是倒序),并且Skip100条记录后返回10条记录的性能,这个测的是Skip和Order对性能的影响

7) 查询100条记录(也就是100KB)的性能(没有排序,没有条件),这个测的是大数据量的查询结果对性能的影响

8) 统计随着测试的进行,总磁盘占用,索引磁盘占用以及数据磁盘占用的数量

并且每一种测试都使用单进程的Mongodb和同一台服务器开三个Mongodb进程作为Sharding(每一个进程大概只能用7GB左右的内存)两种方案

其实对于Sharding,虽然是一台机器放3个进程,但是在查询的时候每一个并行进程查询部分数据,再有运行于另外一个机器的mongos来汇总数据,理论上来说在某些情况下性能会有点提高 Continue reading

mongodb索引讲解与性能调优

mongodb索引规则基本上与传统的关系库一样,大部分优化MySQL/Oracle/SQLite索引的技巧也适用于mongodb。

一、 为什么用索引:

当查询中用到某些条件时,可以对该键建立索引,以提高查询速度。

如果数据量很多且查询多于更新时,可以用索引提高查询的速度。

二、 索引管理:

a)         查询索引:

  1. 查询已有索引的明细:

查询索引很简单,比如说需要查询mailaccess数据库中的Mail collection上的索引时:

mongo                          进入mongo

MongoDB shell version: 1.8.1

connecting to: test

> use mailaccess                  进入mailaccess database

switched to db mailaccess

> db.Mail.getIndexes()             查询索引明细

[

{

“name” : “_id_”,

“ns” : “mailaccess.Mail”,

“key” : {

“_id” : 1

},

“v” : 0

},

{

“_id” : ObjectId(“4df063ac48857df7ac35c348”),

“ns” : “mailaccess.Mail”,

“key” : {

“user” : 1,

“folderId” : 1,

“mailfilename” : 1

},

“name” : “user_1_folderId_1_mailfilename_1”,

“v” : 0

},

…… Continue reading

MongoDB 索引数据类型优化,节省60%内存

最近trunk.ly的工程师通过mongostat发现了大量的page fault,然后通过检查发现,他们的索引已经超出内存限制了(没有keep all index in RAM)。于是他们决定开始减小索引大小,通过测试得出了如下的数据,不同的数据类型的索引大小有2到3倍的差距。

虽然能够想像得到,但是直观的数据图可能让我们更深刻的认识到。他们的测试再一次告诉我们:给索引定一个好的数据结构是多么重要。

这是测试结果图,分别是用int、MongoDB的ObjectID、base64和md5的字符串做索引产生的索引大小:

测试过程也非常简单,首先用下面脚本将各种不同数据结构的数据写入到不同的collection里:

#!/usr/bin/env python

import pymongo
import bson
from pymongo import Connection

db = connection.test_database

print('ObjectID')
for i in range(1, 1000000):
    db.objectids.insert({'i': i})

print('int')
for i in range(1, 1000000):
    db.ints.insert({'_id': i, 'i': i})

print('Base64 BSON')
for i in range(1, 1000000):
    db.base64s.insert({'_id': \
        bson.Binary(hashlib.md5(str(i)).digest(),
        bson.binary.MD5_SUBTYPE), 'i': i})

print('string')
for i in range(1, 1000000):
    db.strings.insert({'_id': hashlib.md5(str(i)).digest(), 'i': i})

然后获取每个collection的index大小,得到如下的结果,画成上面的图:

> db.base64s.stats()
{
        "totalIndexSize" : 67076096,
}
> db.objectids.stats()
{
        "totalIndexSize" : 41598976,
}
> db.ints.stats()
{
        "totalIndexSize" : 32522240,
}
> db.strings.stats()
{
        "totalIndexSize" : 90914816,

}

原文链接:How to save 200% RAM by selecting the right key data type for #MongoDB

相关教程:

三招解决MongoDB的磁盘IO问题

mongodb的监控与性能优化

一.mongodb的监控

mongostat是mongdb自带的状态检测工具,在命令行下使用。它会间隔固定时间获取mongodb的当前运行状态,并输出。如果你发现数据库突然变慢或者有其他问题的话,你第一手的操作就考虑采用mongostat来查看mongo的状态。

立方图片分享

它的输出有以下几列:

  • inserts/s 每秒插入次数
  • query/s 每秒查询次数
  • update/s 每秒更新次数
  • delete/s 每秒删除次数
  • getmore/s 每秒执行getmore次数
  • command/s 每秒的命令数,比以上插入、查找、更新、删除的综合还多,还统计了别的命令
  • flushs/s 每秒执行fsync将数据写入硬盘的次数。
  • mapped/s 所有的被mmap的数据量,单位是MB,
  • vsize 虚拟内存使用量,单位MB
  • res 物理内存使用量,单位MB
  • faults/s 每秒访问失败数(只有Linux有),数据被交换出物理内存,放到swap。不要超过100,否则就是机器内存太小,造成频繁swap写入。此时要升级内存或者扩展
  • locked % 被锁的时间百分比,尽量控制在50%以下吧
  • idx miss % 索引不命中所占百分比。如果太高的话就要考虑索引是不是少了
  • q t|r|w 当Mongodb接收到太多的命令而数据库被锁住无法执行完成,它会将命令加入队列。这一栏显示了总共、读、写3个队列的长度,都为0的话表示mongo毫无压力。高并发时,一般队列值会升高。
  • conn 当前连接数
  • time 时间戳

二.mongodb的优化

mongodb可以通过profile来监控数据,进行优化。 Continue reading

Mongdb监控 (MMS)

MMS (MongoDB Monitoring Service) is a hosted application created by 10gen for monitoring MongoDB deployments. MMS Collects statistics on all key server and hardware indicators and presents this data through an intuitive web interface

先简单说下原理:

1、在mms服务器上添加mongodb服务器的ip,端口,user,password.
2、在mongodb服务器所在的内网空闲机器上安装定制的agent脚本。
3、agent脚本从mms获取你的服务器Ip及端口等信息,然后连接到mongodb服务器获取必要的监控数据。
4、agent脚本将监控信息上传到mms服务器,我们登陆后就可以查看到相应的信息了。

主页地址如下

1.https://mms.10gen.com/help/install.html

在Hosts项上点击添加,此处hostname填写内网IP,port为mongodb端口,user/password为用户名和密码。 Continue reading

三招解决MongoDB的磁盘IO问题

有点标题党的意思,不过下面三招确实比较实用,内容来自Conversocial公司的VP Colin Howe在London MongoDB用户组的一个分享。
申请:下面几点并非放四海皆准的法则,具体是否能够使用,还需要根据自己的应用场景和数据特点来决定。

1.使用组合式的大文档
我们知道MongoDB是一个文档数据库,其每一条记录都是一个JSON格式的文档。比如像下面的例子,每一天会生成一条这样的统计数据:

{ metric: “content_count”, client: 5, value: 51, date: ISODate(“2012-04-01 13:00”) }
{ metric: “content_count”, client: 5, value: 49, date: ISODate(“2012-04-02 13:00”) }

而如果采用组合式大文档的话,就可以这样将一个月的数据全部存到一条记录里:

{ metric: “content_count”, client: 5, month: “2012-04”, 1: 51, 2: 49, … }

通过上面两种方式存储,预先一共存储大约7GB的数据(机器只有1.7GB的内存),测试读取一年信息,这二者的读性能差别很明显: Continue reading

[教程]mongodb常用维护命令

1.客户端常用命令
   #mongo
  >help                       //列出帮助
  >db.help()                //db级别的帮助
>db.mycollection.help()  //collection 级别的帮助

  常用命令:
  >show dbs                     //show database names
  >show collections          //show collections in current database
  >use <db_name>          //set current database
  >db.foo.find()                //list objects in collection foo
  >db.foo.find({a:1})        //list objects in foo where a == 1
  >db.createCollection(name, { size : …, capped : …, max : … } )   //创建collection
  >db.dropDatabase()    //删除库
  >db.collection.count()  //统计colleciton的数量
  >db.collection.drop()    //删除此colleciton
  >db.foo.find().count     //某个数据的数量
  >db.collection.find(…).limit(n)

MongoDB与MySQL的对应关系如下表所示: Continue reading

MongoDB之导入和导出

在上文中,我们了解了教你如何利用MySQL学习MongoDB之授权和权限,本文中我们继续我们的学习之旅,学习两者的导入和导出

1、MySQL导入和导出

(1)、mysqlimport

此工具位于mysql/bin目录中,是MySQL的一个载入(或者说导入)数据的一个非常有效的工具。这是一个命令行工具。有两个参数以及大量的选项可供选择。这个工具把一个文本文件(text file)导入到你指定的数据库和表中。比方说我们要从文件student.txt中把数据导入到数据库class中的表 student中:

mysqlimport class.student student.txt

(2)、load data infile

这个命令与mysqlimport非常相似,但这个方法可以在MySQL命令行中使用。 如mysqlimport工具一样,这个命令也有一些可以选择的参数。比如您需要把自己的电脑上的数据导入到远程的数据库服务器中,您可以使用下面的命令:

Load data local infile “d:\student.txt” into table student;

Continue reading

MongoDB非正常关闭后修复记录 mongod –repair

mongod没有后台执行,在终端连接非正常断开后,再次执行mongod报错,如下所示:

[root@localhost mongodb]# ./bin/mongod
./bin/mongod –help for help and startup options
Thu Nov 17 22:42:49
Thu Nov 17 22:42:49 warning: 32-bit servers don’t have journaling enabled by default. Please use –journal if you want durability.
Thu Nov 17 22:42:49
Thu Nov 17 22:42:49 [initandlisten] MongoDB starting : pid=3257 port=27017 dbpath=/data/db/ 32-bit host=localhost
Thu Nov 17 22:42:49 [initandlisten]
Thu Nov 17 22:42:49 [initandlisten] ** NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data
Thu Nov 17 22:42:49 [initandlisten] **       see http://blog.mongodb.org/post/137788967/32-bit-limitations
Thu Nov 17 22:42:49 [initandlisten] **       with –journal, the limit is lower
Thu Nov 17 22:42:49 [initandlisten]
Thu Nov 17 22:42:49 [initandlisten] db version v2.0.1, pdfile version 4.5
Thu Nov 17 22:42:49 [initandlisten] git version: 3a5cf0e2134a830d38d2d1aae7e88cac31bdd684
Thu Nov 17 22:42:49 [initandlisten] build info: Linux domU-12-31-39-01-70-B4 2.6.21.7-2.fc8xen #1 SMP Fri Feb 15 12:39:36 EST 2008 i686 BOOST_LIB_VERSION=1_41
Thu Nov 17 22:42:49 [initandlisten] options: {}
**************
Unclean shutdown detected.
Please visit http://dochub.mongodb.org/core/repair for recovery instructions.
*************
Thu Nov 17 22:42:49 [initandlisten] exception in initAndListen: 12596 old lock file, terminating
Thu Nov 17 22:42:49 dbexit:
Thu Nov 17 22:42:49 [initandlisten] shutdown: going to close listening sockets…
Thu Nov 17 22:42:49 [initandlisten] shutdown: going to flush diaglog…
Thu Nov 17 22:42:49 [initandlisten] shutdown: going to close sockets…
Thu Nov 17 22:42:49 [initandlisten] shutdown: waiting for fs preallocator…
Thu Nov 17 22:42:49 [initandlisten] shutdown: closing all files…
Thu Nov 17 22:42:49 [initandlisten] closeAllFiles() finished
Thu Nov 17 22:42:49 dbexit: really exiting now

 

修复方法:

这算是一个Mongod 启动的一个常见错误,非法关闭的时候,lock 文件没有干掉,第二次启动的时候检查到有lock 文件的时候,就报这个错误了。 Continue reading

MongoDB update数据语法

在前面的文章“mongodb 查询的语法”里,我介绍了Mongodb的常用查询语法,Mongodb的update操作也有点复杂,我结合自己的使用经验,在这里介绍一下,给用mongodb的朋友看看,也方便以后自己用到的时候查阅:

注:在这篇文章及上篇文章内讲的语法介绍都是在mongodb shell环境内的,和真正运用语言编程(如java,php等)使用时,在使用方法上会有一些差别,但语法(如查询条件,$in,$inc等)是一样的。

本文是参考官方文档来介绍的,之所以有官方文档还要在这介绍,一方面是就当翻译,毕竟每次要用时去看英文文档比较累,第二是官方文档讲解比较简单,有时光看官方文档不好理解,我在实际操作的情况下可以做些补充。 Continue reading