mongoDB配制及学习

日期:2019-10-22编辑作者:www.6165.com

mongoDB配制及学习
分类: 数据库 2011-12-26 14:20 387人阅读 评论(0) 收藏 举报
第意气风发部分 基础篇
第一章 走进MongoDB
MongoDB 是多少个高品质,开源,无形式的文书档案型数据库,是眼前NoSQL 数据库产品中最热
门的人山人海种。它在非常多风貌下可用来取代古板的关系型数据库或键/值存款和储蓄格局,MongoDB 使
用C++开采。MongoDB 的官方网站地址是爬山涉水
此赢得更详尽的消息。

6 / 91
1.1 为何要用NoSQL
1.1.1 NoSQL简介
NoSQL,全称是”Not Only Sql”,指的好坏关系型的数据库。这类数据库入眼有那一个特色爬山涉水非关
系型的、布满式的、开源的、水平可扩大的。原始的指标是为了大范围web 应用,这一场全
新的数据库革命活动开始时代就有人提出,发展至2009 年势头越来越高涨。NoSQL 的维护者们提
倡运用非关系型的数量存款和储蓄,平常的选拔如爬山涉水形式自由、扶植简易复制、轻易的API、最终
的欣欣向荣致性(非ACID)、大体量数据等。NoSQL 被大家用得最多的当数key-value 存款和储蓄,当然还
有其余的文书档案型的、列存款和储蓄、图型数据库、xml 数据库等。相对于近年来层层的关系型数
据库运用,这一概念无疑是大器晚成种全新思维的流入。
1.1.2 发表现状
近来的微型Computer种类布局在多少存款和储蓄方面要求选用架构具有相当大的品位扩张性,而NoSQL 正
在从业于改换那风度翩翩现状。如今新浪天涯论坛的Redis 和谷歌(Google) 的Bigtable 以至亚马逊(Amazon)的SimpleDB
应用的正是NoSQL 型数据库。
NoSQL 项目标名字上看不出什么肖似之处,不过,它们平时在一些地点相近跋山涉水的近义词它们能够拍卖
相当大量的多少。
本场革命前段时间还是供给翘首以待。NoSQL 对大型公司来说还不是主流,不过,热气腾腾四年未来很或者
就能变个标准。在NoSQL 运动的流行二次聚会中,来自世界外市的153位挤满了CBS
Interactive 的活龙活现间会场。分享他们怎样推翻缓慢而昂贵的关周密据库的霸气,怎么样利用更
实用和更方便的法子来治本数据。
关系型数据库给你强加了太多东西。它们要你强行改善对象数据,以满足数据库系统的内需。
在NoSQL 拥护者们来看,基于NoSQL 的数据库替代方案“只是给您所急需的”。
1.1.3 为何是NoSQL
趁着互连网web2.0 网站的起来,非关系型的数据库未来成了一个极端销路广的新领域,非关

7 / 91
周详据库产品的升华极度急速,而古板的关系型数据库在应付web2.0 网址,非常是相当大规
模和高并发的SNS 类型的web2.0 纯动态网址已经体现力不能够支,揭发了广灾殃以克制的问
题,例如:
1、 High performance - 对数据库高并发读写的急需
web2.0 网址要依赖顾客本性化音讯来实时变化动态页面和提供动态新闻,所以基本上不也许
运用动态页面静态化才具,由此数据库并发负载相当高,往往要完成每秒上万次读写需要。
关系型数据库应付上万次SQL 查询还勉强顶得住,不过应付上万次SQL 写多少诉求,硬盘
IO 就曾经心有余而力不足担当了,其实对于常见的BBS 网址,往往也存在对高并发写央浼的须要。
2、Huge Storage - 对海量数据的高效用存款和储蓄和走访的须要
对此大型的SNS 网址,每一日客商发生海量的客户动态消息,以海外的Friend feed 为例,后生可畏
个月就达成了2.5 亿条客商动态,对于关周密据库来讲,在一张2.5 亿条记下的表里面进行
SQL 查询,功用是Infiniti低下以致不可忍受的。再譬喻说大型web 网址的客商登陆系统,例如腾
讯,盛大,动辄数以亿计的帐号,关周到据库也很难应付。
3、High Scalability && High Availability - 对数据库的高可扩张性和高可用性的急需
在依据web 的架构当中,数据库是最难举办横向扩充的,当二个运用系统的客户量和做客
量多如牛毛的时候,你的数据库却不曾办法像web server 和app server 这样轻易的经过抬高
更加的多的硬件和劳务节点来扩展品质和负载手艺。对于许多要求提供24 小时不间断服务的网
站以来,对数据库系统开展进级换代和扩大是特别难过的事情,往往供给停机维护和数量迁移,
可是停机维护随之拉动的正是商号收入的回降。
在上头提到的“三高”须要前边,关周详据库遭逢了难以克制的拦Land Rover,而对此web2.0 网址
来讲,关周密据库的浩大首要特点却一再英雄无发挥专长,比方跋山涉水的近义词
1、数据库事务神采奕奕致性须求
多数web 实时系统并没有必要从严的数据库事务,对读如日中天致性的必要超低,有个别地方对写豆蔻梢头
致性供给也不高。由此数据库事务处理成了数据库高负载下四个沉重的承受。
2、数据库的写实时性和读实时性要求
对关全面据库来讲,插入一条数据以往立即查询,是必然能够读出来那条数据的,可是对于
多多web 应用来讲,并不需要这么高的实时性。
3、对复杂的SQL查询,非常是多表关联合检查询的供给
其余大数据量的web 系统,都拾壹分大忌多少个大表的关系查询,以致头昏眼花的数目深入分析类型的
复杂SQL 报表查询,极度是SNS 类型的网址,从供给以至产品设计角度,就避免了这种情
况的发生。往往更加多的只是单表的主键查询,以至单表的轻易规范分页查询,SQL 的效果被
庞大的削弱了。
为此,关周详据库在这里些越多的采用场景下显得不那么适合了,为了解决那类难题的
NoSQL 数据库应时而生。
NoSQL 是非关系型数据存款和储蓄的广义概念。它打破了一直以来关系型数据库与ACID 理论大学一年级
统的规模。NoSQL 数据存款和储蓄无需固定的表结构,日常也空中楼阁连接操作。在大数目存取
上有所关系型数据库不能比拟的质量优势,该概念在 2008年终收获了相近认可。

8 / 91
明日的运用类别布局亟待多少存储在横向伸缩性上能够知足供给。而 NoSQL 存款和储蓄正是为了
金镶玉裹福禄双全这么些要求。Google 的BigTable 与亚马逊(Amazon) 的Dynamo 是充裕成功的买卖 NoSQL 实现。
有个别开源的 NoSQL 类别,如Twitter 的Cassandra, Apache 的HBase,也博得了广阔认
同。从那几个NoSQL 项目的名字上看不出什么相近之处爬山涉水Hadoop、Voldemort、Dynomite,还
有其余众多,但它们都有一个协同的风味,就是要转移大家对数据库在守旧意义上的驾驭。
1.1.4 NoSQL特点
1、 它能够管理不小量的数码
2、 它运转在便利的PC服务器集群上
PC 集群扩张起来特别有益并且费用好低,防止了思想商业数据库“sharding”操作的深入骨髓
和成本。
3、 它击碎了品质瓶颈
NoSQL 的维护者称,通过NoSQL 架构能够节约将Web 或Java 应用和多少转变到SQL 格式的
时刻,试行进度变得更加快。
“SQL 而不是适用于具备的程序代码”,对于那叁个艰难的再度操作的数额,SQL 值得花钱。但
是当数据库结构特轻巧时,SQL 恐怕未有太大用处。
4、 它未有过多的操作
就算NoSQL 的维护者也认同关系型数据库提供了独步有时的效率集聚,何况在数据完整性
上也发挥相对稳固,他们同临时候也象征,集团的切切实实必要恐怕未有那么复杂。
5、 它的跟随者源于社区
因为NoSQL 项目都以开源的,因而它们贫乏代理商提供的标准援救。这或多或少它们与大部分
开源项目相仿,不能不从社区中谋求扶助。
NoSQL 发展到现在,出现了一些种非关系性数据库,本书就以NoSQL 中近些日子展现最棒的
MongoDB 为例来开展验证。
1.2 初识MongoDB
MongoDB 是贰个在意关周密据库和非关周全据库之间的制品,是非关周密据库在那之中效能最
增多,最像关周详据库的。他补助的数据结构极度松懈,是看似json 的bjson 格式,因而可
以存款和储蓄比较复杂的数据类型。MongoDB 最大的特色是他援救的询问语言特别常有力,其语法
稍许近似于面向对象的查询语言,大约能够完毕相近关周到据库单表查询的多边职能,
再者还协助对数码建构目录。它是一个面向集合的,形式自由的文书档案型数据库。
1、 面向集结(Collenction-Orented)
意思是数额被分组存款和储蓄在数额聚集, 被可以称作三个会面(Collenction)。每种集结在数据库中
都有多少个唯如日方升的标记名,何况能够包罗Infiniti数指标文书档案。集结的定义近似关系型数据库

9 / 91
(RubiconDBMS)里的表(table),区别的是它不必要定义任何情势(schema)。
2、 方式自由(schema-free)
代表对于仓库储存在MongoDB 数据库中的文件,我们没有须求掌握它的别的协会定义。提了那
么数十次"无形式"或"方式自由",它到是个什么概念呢?举例,下边三个记录能够存在于风流倜傥致
mongoDB配制及学习。个聚众里面爬山涉水
{"welcome" : "Beijing"}
{"age" : 25}
3、 文档型
情趣是我们存款和储蓄的数目是键-值对的集结,键是字符串,值能够是数据类型群集里的任性等级次序,
席卷数组和文书档案. 大家把那些数目格式称作 “BSON” 即 “Binary 塞里alized dOcument
Notation.”
上边将分别介绍MongoDB 的特色、作用和适用场地。
1.2.1 特点
面向群集存款和储蓄,易于存款和储蓄对象类型的数量
格局自由
扶持动态查询
帮忙完全索引,包罗在那之中对象
支撑查询
支撑复制和故障恢复生机
行使便捷的二进制数据存储,蕴涵大型对象(如录制等)
自动管理碎片,以接济云总计档期的顺序的扩充性
支持Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及C++语言的驱动程序,社区
中也提供了对Erlang 及.NET 等平台的驱动程序
文本存款和储蓄格式为BSON(少年老成种JSON 的恢弘)
可透过互连网访谈
1.2.2 功能
面向集结的囤积爬山涉水符合储存对象及JSON 格局的多少
动态查询爬山涉水MongoDB 援救增加的查询表明式。查询指令使用JSON 情势的符号,可自由
查询文书档案中内嵌的目的及数组
全部的目录扶持爬山涉水包罗文档内嵌对象及数组。MongoDB 的询问优化器会解析查询表明
式,并扭转贰个便捷的询请安排
询问监视跋山涉水的近义词MongoDB 包罗大器晚成多级监视工具用于深入分析数据库操作的特性
复制及自动故障转移爬山涉水MongoDB 数据库扶助服务器之间的数量复制,帮忙主-从方式及
服务器之间的互相复制。复制的要紧指标是提供冗余及机关故障转移
快速的观念意识存款和储蓄形式跋山涉水的近义词协助二进制数据及重型对象(如照片或图表)
活动分片以支撑云级其他伸缩性爬山涉水自动分片成效协理水平的数据库集群,可动态加多额

10 / 91
外的机械
1.2.3 适用场馆
网址数据跋山涉水的近义词MongoDB 特别相符实时的插入,更新与查询,并富有网址实时数据存储所
需的复制及中度伸缩性
缓存跋山涉水的近义词由于品质非常高,MongoDB 也契同盟为音讯基础设备的缓存层。在系统重启之后,
由MongoDB 搭建的长久化缓存层可防止止下层的数据源过载
大尺寸,实惠值的数额爬山涉水使用古板的关系型数据库存款和储蓄一些数量时或然会相比较高昂,在
此从前,相当多时候程序猿往往会采取古板的文书实行仓库储存
高伸缩性的光景爬山涉水MongoDB 特别相符由数十或数百台服务器组成的数据库。MongoDB
的门道图中早就包含对MapReduce 引擎的放手销持
用于对象及JSON 数据的蕴藏跋山涉水的近义词MongoDB 的BSON 数据格式非常符合文书档案化格式的积攒
及查询
其次章 安装和安排
MongoDB 的法定下载站是
次第下来。在下载页面可以见到,它对操作系统帮忙很全面,如OS X、Linux、Windows、Solaris
都帮助,并且都有各自的32 位和64 位版本。方今的安居版本是1.8.1 版本。
注意:

  1. MongoDB 1.8.1 Linux 版须求glibc 必须是2.5 以上,所以要求先认同操作系统的glibc 的版
    本,作者最早用Linux AS 4 安装不上,最后用的是ENCOREHEL5 来安装才成功的。
  2. 在32 位平台MongoDB 差异意数据库文件(累加总额)当先2G,而六十几人平台未有这些
    限制。
    怎么设置 MongoDB 数据库呢?上边将各自介绍Windows 和Linux 版本的设置方式

11 / 91
2.1 Windows平台的设置
步骤一: 下载MongoDB
url 下载地址:
手续二: 设置MongoDB程序寄存目录
将其解压到 c:,再重命名称叫mongo,路线为c:mongo
步骤三: 设置数据文件寄存目录
在c:盘建一个db 文件夹,路线c:db
步骤四: 启动MongoDB服务
步向 cmd 提醒符调控台,c:mongobinmongod.exe --dbpath=c:db
C:mongobin>C:mongobinmongod --dbpath=c:db
Sun Apr 10 22:34:09 [initandlisten] MongoDB starting : pid=5192 port=27017 dbpat
h=d:datadb 32-bit
** NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data
** see
** with --dur, the limit is lower
……
Sun Apr 10 22:34:09 [initandlisten] waiting for connections on port 27017
Sun Apr 10 22:34:09 [websvr] web admin interface listening on port 28017
MongoDB 服务端的暗中认可监听端口是 27017
步骤五: 将MongoDB作为 Windows 服务随机运维
先创建C:mongologsmongodb.log 文件,用于存款和储蓄MongoDB 的日志文件, 再设置系统
服务。
C:mongobin>C:mongobinmongod --dbpath=c: db --logpath=c:mongolo
gsmongodb.log --install
all output going to: c:mongologsmongodb.log
Creating service MongoDB.
Service creation successful.
Service can be started from the command line via 'net start "MongoDB"'.
C:mongobin>net start mongodb
Mongo DB 服务业已起步成功。
C:mongobin>
步骤六: 客商端连接验证
新开采一个CMD 输入爬山涉水c:mongobinmongo,假设出现下边提醒,那么你就足以起来
MongoDB 之旅了
C:mongobin>c:mongobinmongo
MongoDB shell version: 1.8.1
connecting to: test
>
步骤七: 查看MongoDB日志
查看C:mongologsmongodb.log 文件,就可以对MongoDB 的运作境况开展查看或排错了,
这么就完了了Windows 平台的MongoDB 安装。

12 / 91
2.2 Linux平台的装置
步骤一: 下载MongoDB
下载安装包跋山涉水的近义词curl -O
步骤二: 设置MongoDB程序贮存目录
将其解压到/Apps,再重命名字为mongo,路线为/Apps/mongo
手续三: 设置数据文件贮存目录
建立/data/db 的目录, mkdir –p /data/db
步骤四: 启动MongoDB服务
/Apps/mongo/bin/mongod --dbpath=/data/db
[root@localhost ~]# /Apps/mongo/bin/mongod --dbpath=/data/db
Sun Apr 8 22:41:06 [initandlisten] MongoDB starting : pid=13701 port=27017 dbpath=/data/db
32-bit
** NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data
** see
** with --dur, the limit is lower
……
Sun Apr 8 22:41:06 [initandlisten] waiting for connections on port 27017
Sun Apr 8 22:41:06 [websvr] web admin interface listening on port 28017
MongoDB 服务端的默许连接端口是 27017
手续五: 将MongoDB作为 Linux 服务随机运转
先创设/Apps/mongo/logs/mongodb.log 文件,用于存款和储蓄MongoDB 的日记文件
vi /etc/rc.local, 使用vi 编辑器展开配置文件,并在中间插足下边后生可畏行代码
/Apps/mongo/bin/mongod --dbpath=/data/db --logpath=/Apps/mongo/logs/mongodb.log
步骤六: 客商端连接验证
新开发一个Session 输入爬山涉水/Apps/mongo/bin/mongo,借使现身下边提醒,那么你就能够
开始MongoDB 之旅了
[root@localhost ~]# /Apps/mongo/bin/mongo
MongoDB shell version: 1.8.1
connecting to: test
>
步骤七: 查看MongoDB日志
查看/Apps/mongo/logs/mongodb.log 文件,就能够对MongoDB 的运营处境实行查看或分
析了
[root@localhost logs]# ll
总计 0
-rw-r--r-- 1 root root 0 04-08 20:15 mongodb.log
[root@localhost logs]#
上述的多少个步骤就OK 了!!那样三个简练的MongoDB 数据库就足以七通八达地运维起
来了。

13 / 91
其三章 种类布局
MongoDB 是多少个可移植的数据库,它在风靡的每三个平台上都足以利用,即所谓的跨平台
特点。在不一样的操作系统上即使略大有不一样,但是从完整构架上来看,MongoDB 在不一致的平
台上是如出如日方升辙的,如数据逻辑结商谈数量的存款和储蓄等等。
八个运作着的MongoDB 数据库就足以视作是三个MongoDB Server,该Server 由实例和数量
库组成,在相像的图景下三个MongoDB Server 机器上带有四个实例和七个与之相应的数量
库,不过在特殊情状下,如硬件投入成本有限或特种的应用要求,也允许三个Server 机器
上得以有八个实例和三个数据库。
MongoDB 中大器晚成多级物理文件(数据文件,日志文件等)的成团或与之相应的逻辑结构(集
合,文书档案等)被喻为数据库,简单的讲,就是数据库是由蒸蒸日上体系与磁盘有涉嫌的物理文件的
组成。
3.1 数据逻辑结构
不菲人在就学MongoDB 连串布局的时候会际遇各式各样的标题,笔者在此边给大家轻巧的介
绍一下MongoDB 连串布局之-的逻辑结构。MongoDB 的逻辑结构是蒸蒸日上种等级次序结构。首要由跋山涉水的近义词
文书档案(document)、集结(collection)、数据库(database)那三有个别组成的。逻辑结构是面向客户
的,客商使用MongoDB 开辟应用程序使用的便是逻辑结构。
MongoDB 的文书档案(document),也便是关全面据库中的豆蔻梢头行记录。
七个文书档案组成多少个晤面(collection),相当于关周密据库的表。
七个聚众(collection),逻辑上组织在联合,正是数据库(database)。
多少个MongoDB 实例支持三个数据库(database)。
文书档案(document)、集合(collection)、数据库(database)的档案的次序结构如下图:

14 / 91
对于习于旧贯了关系型数据库的心上人们,笔者将MongoDB 与关系型数据库的逻辑结构进行了相比,
以便让大家更加深厚的理解MongoDB 的逻辑结构
逻辑结构相比较
MongoDB 关系型数据库
文档(document) 行(row)
集合(collection) 表(table)
数据库(database) 数据库(database)
3.2 数据存款和储蓄结构
MongoDB 对境内客商来讲比较新, 它就好像三个黑盒子,不过若是对于它里面包车型客车数码存储
掌握多某些来讲,那么将会急迅的知情和驾乘MongoDB,让它致以它越来越大的坚决守护。
MongoDB 的默许数据目录是/data/db,它担当积存全部的MongoDB 的数据文件。在MongoDB
中间,种种数据库都带有三个.ns 文书和局部数据文件,並且那几个数据文件会随着数据量的
扩张而变得进一步多。所以倘若系统中有贰个名字为foo 的数据库,那么结合foo 这么些数据库
的文书就能够由foo.ns,foo.0,foo.1,foo.2 等等组成,具体如下:

15 / 91
[root@localhost db]# ll /data/db/
总计 196844
-rw------- 1 root root 16777216 04-15 16:33 admin.0
-rw------- 1 root root 33554432 04-15 16:33 admin.1
-rw------- 1 root root 16777216 04-15 16:33 admin.ns
-rw------- 1 root root 16777216 04-21 17:30 foo.0
-rw------- 1 root root 33554432 04-21 17:30 foo.1
-rw------- 1 root root 67108864 04-21 17:30 foo.2
-rw------- 1 root root 16777216 04-21 17:30 foo.ns
-rwxr-xr-x 1 root root 6 04-21 17:16 mongod.lock
-rw------- 1 root root 16777216 04-15 16:30 test.0
-rw------- 1 root root 33554432 04-15 16:30 test.1
-rw------- 1 root root 16777216 04-15 16:30 test.ns
drwxr-xr-x 2 root root 4096 04-21 17:30 _tmp
MongoDB 内部有预分配空间的编写制定,每种预分配的公文都用0 举办填充,由于有了这么些机
制, MongoDB 始终维持额外的空花潮空余的数据文件,从而使得制止了由于数量暴增而带来
的磁盘压力过大的标题。
出于表中数据量的充实,数据文件每新分配一遍,它的高低都会是上二个数据文件大小的2
倍,每一个数据文件最大2G。那样的体制有助于防备十分小的数据库浪费过多的磁盘空间,同
时又能担保非常的大的数据库有对应的留给空间应用。
数据库的每张表都对应一个命名空间,每种索引也会有照拂的命名空间。这一个命名空间的元数
据都聚焦在*.ns 文件中。
在下图中,foo 这几个数据库包涵3 个公文用于存储表和目录数据,foo.2 文件属于预分配的空
文本。foo.0 和foo.1 那多个数据文件被分成了对应的盘区对应区别的名字空间。

16 / 91
上海体育场地呈现了命名空间和盘区的涉及。每个命名空间能够分包多少个例外的盘区,那些盘区并不
是接连的。与数据文件的增高相仿,每一个命名空间对应的盘区大小的也是随着分配的次数
反复进步的。那样做的指标是为了平衡命名空间浪费的上空与维持某贰个命名空间中多少的
三番五次性。上航海用体育场面中还会有三个亟需注意的命名空间爬山涉水$freelist,这些命名空间用于记录不再动用
的盘区(被剔除的Collection 或索引)。每当命名空间供给分配新的盘区的时候,都会先查
看$freelist 是不是有高低适当的盘区能够动用,那样就回收空闲的磁盘空间。
第四章 快速入门
MongoDB Shell 是MongoDB 自带的交互式Javascript shell,用来对MongoDB 进行操作和处理
的交互式景况。
使用 "./mongo --help" 可查阅相关连接参数,上边将从广大的操作,如插入,查询,改过,
除去等多少个地点演说MongoDB shell 的用法。
4.1 运营数据库
MongoDB 安装、配置完后,必需先运行它,然后技巧动用它。怎么运行它吗?下边分别展
示了3 种办法来运转实例。
4.1.1 命令行方式运营
MongoDB 暗许存款和储蓄数据目录为/data/db/ (大概 c:datadb), 私下认可端口27017,暗中同意HTTP 端

17 / 91
口28017。当然你也能够订正成不一样目录,只要求内定dbpath 参数: /Apps/mongo/bin/mongod
--dbpath=/data/db
[root@localhost ~]# /Apps/mongo/bin/mongod --dbpath=/data/db
Sun Apr 8 22:41:06 [initandlisten] MongoDB starting : pid=13701 port=27017 dbpath=/data/db
32-bit
……
Sun Apr 8 22:41:06 [initandlisten] waiting for connections on port 27017
Sun Apr 8 22:41:06 [websvr] web admin interface listening on port 28017
4.1.2 配置文件格局运行
只即便贰个正规的DBA,那么实例运行时会加非常多的参数以便使系统运维的极其安静,那样
就大概会在运维时在mongod 后边加一长串的参数,看起来十三分混乱并且倒霉管护,
那正是说有啥样措施让这几个参数有系统呢?MongoDB 也帮衬同mysql 相近的读取运维配置文件
的秘诀来运营数据库,配置文件的内容如下:
[root@localhost bin]# cat /etc/mongodb.cnf
dbpath=/data/db/
运营时加上”-f”参数,并针对配置文件就能够
[root@localhost bin]# ./mongod -f /etc/mongodb.cnf
Mon May 28 18:27:18 [initandlisten] MongoDB starting : pid=18481 port=27017
dbpath=/data/db/ 32-bit
……
Mon May 28 18:27:18 [initandlisten] waiting for connections on port 27017
Mon May 28 18:27:18 [websvr] web admin interface listening on port 28017
4.1.3 Daemon形式运营
大家能够当心到地方的三种艺术都慢在前台运维MongoDB 进度,但当运转MongoDB 进度
的session 窗口相当的大心关闭时,MongoDB 进度也将随时告如火如荼段落,这无疑是相当不安全的,还好
MongoDB 提供了意气风发种后台Daemon 格局运行的筛选,只需加上四个”--fork”参数就能够,那
就使我们能够更有利的操作数据库的启航,但若是用到了”--fork”参数就非得也启用”
--logpath”参数,那是强制的
[root@localhost ~]# /Apps/mongo/bin/mongod --dbpath=/data/db --fork
--fork has to be used with --logpath
[root@localhost ~]# /Apps/mongo/bin/mongod --dbpath=/data/db --logpath=/data/log/r3.log
--fork
all output going to: /data/log/r3.log
forked process: 19528
[root@localhost ~]#

18 / 91
4.1.4 mongod参数表明
最轻巧易行的,通过推行mongod 即能够运转MongoDB 数据库服务,mongod 帮忙广大的参数,
但都有默许值,个中最根本的是须要钦定数据文件路线,恐怕保障暗中同意的/data/db 存在而且
有访谈权限,不然运行后会自动关闭服务。Ok,那也正是说,只要确定保障dbpath 就足以运营
MongoDB 服务了
mongod 的首要参数有爬山涉水
dbpath:
数据文件寄放路线,各个数据库会在内部创设多个子目录,用于防止同三个实例数次运
行的mongod.lock 也保留在这里目录中。
logpath
荒诞日志文件
logappend
荒谬日志采纳增添形式(暗中认可是覆写方式)
bind_ip
对外地劳工务的绑定ip,平常安装为空,及绑定在本机全体可用ip 上,如有须要能够独立
指定
port
对外服务端口。Web 管理端口在此个port 的根底上+1000
fork
从今以后台Daemon 方式运转服务
journal
张开日志作用,通过保留操作日志来下滑单机故障的重作冯妇时间,在1.8 版本后正式加盟,
代替在1.7.5 版本中的dur 参数。
syncdelay
系统同步刷新磁盘的时光,单位为秒,暗中认可是60 秒。
directoryperdb
各样db 寄存在独立的目录中,建议设置该参数。与MySQL 的独立表空间肖似
maxConns
最重庆接数
repairpath
实行repair 时的近日目录。在若无拉开journal,至极down 机后重启,必须实行repair
操作。
在源代码中,mongod 的参数分为经常参数,windows 参数,replication 参数,replica set 参
数,以致含有参数。上面列举的都以相通参数。借使要配备replication,replica set 等,还需
要安装相应的参数,这里先不开展,后续会有特别的章节来描述。推行mongod --help 能够
看看对绝大许多参数的解说,但有一点包涵参数,则不能不通过看代码来赢得(见db.cpp
po::options_description hidden_options(“Hidden options”);),隐含参数通常仍为还在支付
中,要么是准备舍弃,因而在生育条件中不建议使用。
想必您曾经注意到,mongod 的参数中,没有设置内部存款和储蓄器大小相关的参数,是的,MongoDB 使

19 / 91
用os mmap 机制来缓存数据文件数量,自个儿近日不提供缓存机制。这样好处是代码简单,
mmap 在数据量不抢先内部存款和储蓄器时功能相当高。不过数据量超过系统可用内存后,则写入的性质可
能不太平静,轻巧并发起伏,可是在风行的1.8 版本中,这几个情况绝对早先的版本现已
有了迟早水准的校勘。
那样多参数,周密写在指令行中则轻便零乱而倒霉管理。由此,mongod 帮衬将参数写入到
mongoDB配制及学习。七个配置文本文件中,然后经过config 参数来援用此布局文件爬山涉水
./mongod --config /etc/mongo.cnf
4.2 结束数据库
MongoDB 提供的告风流倜傥段落数据库命令也非常丰硕,假如Control-C、发送shutdownServer()指令及
发送Unix 系统中断时域信号等
4.2.1 Control-C
举例管理连接情形,那么直接能够经过Control-C 的法门去终止MongoDB 实例,具体如下:
[root@localhost ~]# /Apps/mongo/bin/mongo --port 28013
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:28013/test
> use test
switched to db test
> ^C[root@localhost ~]#
4.2.2 shutdownServer()指令
设若拍卖连接景况,那么直接能够透过在admin 库中发送db.shutdownServer()指令去终止
MongoDB 实例,具体如下:
[root@localhost ~]# /Apps/mongo/bin/mongo --port 28013
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:28013/test
> use admin
switched to db admin
> db.shutdownServer()
Thu May 31 23:22:00 DBClientCursor::init call() failed
Thu May 31 23:22:00 query failed : admin.$cmd { shutdown: 1.0 } to: 127.0.0.1:28013
server should be down...
Thu May 31 23:22:00 trying reconnect to 127.0.0.1:28013
Thu May 31 23:22:00 reconnect 127.0.0.1:28013 failed couldn't connect to server
127.0.0.1:28013
Thu May 31 23:22:00 Error: error doing query: unknown shell/collection.js:150
>

20 / 91
4.2.3 Unix系统指令
在找到实例的长河后,恐怕通过发送kill -2 PID 或kill -15 PID 来终止进度
[root@localhost ~]# ps aux|grep mongod
root 19269 0.3 1.3 76008 3108 Sl 23:24 0:00 /Apps/mongo/bin/mongod --fork
--port 28013
[root@localhost ~]# kill -2 19269
注意:
不要用kill -9 PID 来杀死MongoDB 进程,那样可以会导致MongoDB 的数量损坏
4.3 连接数据库
近些日子大家就足以利用自带的MongoDB shell 工具来操作数据库了. (大家也得以运用各类编制程序
言语的驱动来行使MongoDB, 但自带的MongoDB shell 工具得以一本万利我们管理数据库)。
新开垦叁个Session 输入爬山涉水/Apps/mongo/bin/mongo,假诺出现上面提醒,那么你就证实连接
上数据库了,能够开展操作了
[root@localhost ~]# /Apps/mongo/bin/mongo
MongoDB shell version: 1.8.1
connecting to: test
>
暗中同意 shell 连接的是本机localhost 下面的 test 库,"connecting to:" 这些会展现你正在使用
的数据库的名称. 想换数据库的话能够用”use mydb”来完成。
4.4 插入记录
下边大家来创设一个test 的聚焦并写入一些数据. 创立四个对象j 和t , 并保存到聚集中去.
在例子里 “>” 来代表是 shell 输入提醒符
> j = { name : "mongo" };
{"name" : "mongo"}
> t = { x : 3 };
{ "x" : 3 }
> db.things.save(j);
> db.things.save(t);
> db.things.find();
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x" : 3 }
>
有几点须要小心一下:
没有要求事先创设三个集合. 在第三次插入数据时候会自动创制.

21 / 91
在文书档案中其实能够积存任何协会的数据, 当然在事实上行使大家存款和储蓄的或许一样类型文
档的群集. 那个特点其实能够在行使里很灵敏, 你无需肖似alter table 语句来改良你
的数据结构
历次插入数据时候会集中都会有叁个ID, 名字叫 _id.
下边再加点数据:
> for( var i = 1; i < 10; i++ ) db.things.save( { x:4, j:i } ); > db.things.find();
{"name" : "mongo" , "_id" : ObjectId("497cf60751712cf7758fbdbb")}
{"x" : 3 , "_id" : ObjectId("497cf61651712cf7758fbdbc")}
{"x" : 4 , "j" : 1 , "_id" : ObjectId("497cf87151712cf7758fbdbd")}
{"x" : 4 , "j" : 2 , "_id" : ObjectId("497cf87151712cf7758fbdbe")}
{"x" : 4 , "j" : 3 , "_id" : ObjectId("497cf87151712cf7758fbdbf")}
{"x" : 4 , "j" : 4 , "_id" : ObjectId("497cf87151712cf7758fbdc0")}
{"x" : 4 , "j" : 5 , "_id" : ObjectId("497cf87151712cf7758fbdc1")}
{"x" : 4 , "j" : 6 , "_id" : ObjectId("497cf87151712cf7758fbdc2")}
{"x" : 4 , "j" : 7 , "_id" : ObjectId("497cf87151712cf7758fbdc3")}
{"x" : 4 , "j" : 8 , "_id" : ObjectId("497cf87151712cf7758fbdc4")}
请留意一下, 这里循环次数是10, 可是只体现到第8 条, 还会有2 条数据未有呈现. 倘诺想继
续查询上面包车型地铁数额只须要利用”it”命令, 就能一而再呈现上面包车型地铁多寡:
{ "_id" : ObjectId("4c220a42f3924d31102bd866"), "x" : 4, "j" : 17 }
{ "_id" : ObjectId("4c220a42f3924d31102bd867"), "x" : 4, "j" : 18 }
has more
> it
{ "_id" : ObjectId("4c220a42f3924d31102bd868"), "x" : 4, "j" : 19 }
{ "_id" : ObjectId("4c220a42f3924d31102bd869"), "x" : 4, "j" : 20 }
从本事上讲 find() 重返二个游标对象. 但在上头的例子里, 并未有获得多个游标的变量. 所
以 shell 自动遍历游标, 重返多少个发轫化的set, 并允许大家一而再用 it 迭代输出.
本来大家也得以从来用游标来输出, 然而那一个是”游标”部分的剧情了.
4.5 _id key
MongoDB 援助的数据类型中,_id 是其自有产物,上面前蒙受其做些轻松的介绍。
储存在MongoDB 集结中的每一种文档(document)都有三个暗许的主键_id,这些主键名称是
恒久的,它能够是MongoDB 扶植的别的数据类型,暗中同意是ObjectId。在关周详据库schema
统筹中,主键多数是数值型的,比方常用的int 和long,并且更平凡的是主键的取值由数据
库自增得到,这种主键数值的有序性不经常也标记了某种逻辑。反观MongoDB,它在规划之
初就稳固于布满式存款和储蓄系统,所以它原生的不扶植自增主键。
_id key 举例表明 :
当大家在往三个集合中写入一条文书档案时,系统会自动生成二个名叫_id 的key.如:
> db.c1.find()
{ "_id" : ObjectId("4fb5faaf6d0f9d8ea3fc91a8"), "name" : "Tony", "age" : 20 }
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }

22 / 91
此处多出了五个连串为ObjectId 的key ,在插入时并未有一些名,那有一点点形似Oracle 的rowid
的音讯,属于自动生成的。
在MongoDB 中,每多少个聚焦都不得不有二个称呼_id 的字段,字段类型暗许是ObjectId ,换句话
说,字段类型能够不是ObjectId,比如:
> db.c1.find()
{ "_id" : ObjectId("4fb5faaf6d0f9d8ea3fc91a8"), "name" : "Tony", "age" : 20 }
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }
{ "_id" : 3, "name" : "Bill", "age" : 55 }
虽然_id 的品类能够随便内定,可是在同贰个汇聚中必需唯新生事物正在蒸蒸日上,借使插入重复的值的话,系统
将会抛出非常,具体如下:
> db.c1.insert({_id:3, name:"Bill_new", age:55})
E11000 duplicate key error index: test.c1.$_id_ dup key: { : 3.0 }
>
因为前边早已插入了一条_id=3 的笔录,所以再插入相近的文书档案就不容许了。
4.6 查询记录
4.6.1 普通查询
在并未有浓烈查询在此之前, 大家先看看怎么从贰个查询中回到二个游标对象. 能够总结的通过
find() 来询问, 他回来一个大肆结构的集结. 假若落成特定的询问稍后解说.
兑现地点相通的查询, 然后经过 while 来输出:
> var cursor = db.things.find();
> while (cursor.hasNext()) printjson(cursor.next());
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x" : 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x" : 4, "j" : 1 }
{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "x" : 4, "j" : 2 }
{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x" : 4, "j" : 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x" : 4, "j" : 4 }
{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "x" : 4, "j" : 5 }
下边包车型客车事例突显了游标风格的迭代输出. hasNext() 函数告诉大家是或不是还大概有数目, 要是有则
能够调用 next() 函数.
当大家运用的是 JavaScript shell, 能够用到JS 的表征, forEach 就足以输出行标了. 上边的例
子正是使用 forEach() 来循环输出: forEach() 必需定义四个函数供每一种游标元素调用.
> db.things.find().forEach(printjson);
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x" : 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x" : 4, "j" : 1 }

23 / 91
{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "x" : 4, "j" : 2 }
mongoDB配制及学习。{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x" : 4, "j" : 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x" : 4, "j" : 4 }
{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "x" : 4, "j" : 5 }
在 MongoDB shell 里, 大家也足以把游标当做数组来用:
> var cursor = db.things.find();
> printjson(cursor[4]);
{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x" : 4, "j" : 3 }
采取游标时候请留意占用内部存款和储蓄器的主题素材, 非常是相当大的游标对象, 有望会内存溢出. 所以应
该用迭代的艺术来输出. 下边包车型大巴亲自过问则是把游标转变来真实的数组类型:
> var arr = db.things.find().toArray();
> arr[5];
{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x" : 4, "j" : 4 }
请稳重那一个特征只是在MongoDB shell 里使用, 实际不是两全的别的应用程序驱动都扶助.
MongoDB 游标对象不是向来非常慢速照相,如若有别的客户在集聚里首先次如故最终一回调用
next(), 你或者得不到游标里的数据. 所以要猛烈的锁定你要查询的游标.
4.6.2 条件查询
到那边大家曾经精通怎么从游标里达成多个询问并再次来到数据对象, 上面就来拜谒怎么依据
点名的条件来查询.
上边包车型地铁亲自过问正是认证什么试行一个近似SQL 的询问, 并演示了怎么在 MongoDB 里福如东海. 那
是在MongoDB shell 里询问, 当然你也能够用别的的应用程序驱动大概语言来落到实处:
SELECT * FROM things WHERE name="mongo"
> db.things.find({name:"mongo"}).forEach(printjson);
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
SELECT * FROM things WHERE x=4
> db.things.find({x:4}).forEach(printjson);
{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x" : 4, "j" : 1 }
{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "x" : 4, "j" : 2 }
{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "x" : 4, "j" : 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "x" : 4, "j" : 4 }
{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "x" : 4, "j" : 5 }
询问条件是 { a:A, b:B, … } 相像 “where a==A and b==B and …”.
上边呈现的是具备的因素, 当然我们也得以回来特定的元素, 形似于重临表里某字段的值,
只须要在 find({x:4}) 里钦赐成分的名字
SELECT j FROM things WHERE x=4
> db.things.find({x:4}, {j:true}).forEach(printjson);

24 / 91
{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "j" : 1 }
{ "_id" : ObjectId("4c220a42f3924d31102bd857"), "j" : 2 }
{ "_id" : ObjectId("4c220a42f3924d31102bd858"), "j" : 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd859"), "j" : 4 }
{ "_id" : ObjectId("4c220a42f3924d31102bd85a"), "j" : 5 }
4.6.3 findOne()语法
为了方便思虑, MongoDB shell 防止游标或然带来的耗费, 提供叁个findOne() 函数. 这些函
数和 find() 函数同样, 可是它回到的是游标里第一条数据, 也许重回null,即空数据.
用作叁个例子, name=”mongo” 能够用数不完主意来贯彻, 可以用 next() 来循环游标只怕当
做数组再次来到第一个成分.
只是用 findOne() 方法规更简便和火速:
> printjson(db.things.findOne({name:"mongo"}));
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
4.6.4 通过limit限定结果集数量
就算必要约束结果集的长度, 那么能够调用 limit 方法.
那是猛烈推荐消除质量难题的法子, 就是通过限定条数来收缩互联网传输, 举个例子:
> db.things.find().limit(3);
{ "_id" : ObjectId("4c2209f9f3924d31102bd84a"), "name" : "mongo" }
{ "_id" : ObjectId("4c2209fef3924d31102bd84b"), "x" : 3 }
{ "_id" : ObjectId("4c220a42f3924d31102bd856"), "x" : 4, "j" : 1 }
4.7 修改记录
将name 是mongo 的笔录的name 校正为mongo_new
> db.things.update({name:"mongo"},{$set:{name:"mongo_new"}});
我们来询问一下是还是不是修正来了
> db.things.find();
{ "_id" : ObjectId("4faa9e7dedd27e6d86d86371"), "x" : 3 }
{ "_id" : ObjectId("4faa9e7bedd27e6d86d86370"), "name" : "mongo_new" }
4.8 删除记录
将用户name 是mongo_new 的记录从集合things 中剔除

25 / 91
> db.things.remove({name:"mongo_new"});
> db.things.find();
{ "_id" : ObjectId("4faa9e7dedd27e6d86d86371"), "x" : 3 }
经求证,该记录确实被剔除了
4.9常用工具集
MongoDB 在bin 目录下提供了一文山会海有效的工具,那个工具提供了MongoDB 在运营管理上
的方便。
bsondump: 将bson 格式的文本转储为json 格式的数额
mongo: 客户端命令行工具,其实也是八个js 解释器,扶持js 语法
mongod: 数据库服务端,种种实例运行贰个经过,能够fork 为后台运维
mongodump/ mongorestore: 数据库备份和还原工具
mongoexport/ mongoimport: 数据导出和导入工具
mongofiles: GridFS 管理工科具,可完结二制文件的存取
mongos: 分片路由,如若选用了sharding 作用,则应用程序连接的是mongos 而不是
mongod
mongosniff: 这黄金时代工具的功力相同于tcpdump,不一样的是她只监察和控制MongoDB 相关的包请
求,而且是以内定的可读性的款式出口
mongostat: 实时品质监察和控制工具
4.10 客户端GUI 工具
看二个出品是或不是拿走认可,能够从五个侧边看其第三方工具的多少和干练程度,上面大家就来
细数一下MongoDB 常用的GUI 管理工科具。
4.10.1 MongoVUE
主页:
三个桌面程序,提供了对MongoDB 数据库的基本操作,如查看、查询、更新、删除等,简
单易用,然而效果还比较弱,未来发展应当科学。

26 / 91
4.10.2 RockMongo
主页:
罗克Mongo 是三个PHP5 写的MongoDB 管理工具。
主要特征:
动用宽松的New BSD License 公约
进程快,安装简便
支撑多语言(近期提供普通话、乌克兰语、韩语、巴西联邦共和国葡萄牙共和国语、克罗地亚语、阿拉伯语)
系统能够安插多个主机,各种主机能够有多少个管理员,必要管理员密码技能登陆操作,确定保障
数据库的安全性

27 / 91
服务器新闻 (WEB 服务器, PHP, PHP.ini 相关指令 ...)状态
多少查询,创设和删除
试行命令和Javascript 代码
4.10.3 MongoHub
主页:
MongoHub 是一个指向性Mac 平台的MongoDB 图形处理顾客端,可用来保管MongoDB 数据
的应用程序。
其次部分 应用篇
本章将结合实际应用,珍视演说一些实际上中国人民解放军海军事工业程高校业作中最常用的措施。
第五章 高端查询
面向文书档案的NoSQL 数据库珍视化解的主题素材不是高品质的并发读写,而是保险海量数据存款和储蓄
的还要,具备优秀的询问质量。
MongoDB 最大的特点是他匡助的询问语言非常强盛,其语法有一些形似于面向对象的查询语
言,大致可以达成相通关全面据库单表查询的大举功力,何况还支持对数码创立目录。

28 / 91
谈起底由于MongoDB 能够支撑复杂的数据结构,而且蕴藏强盛的数据查询成效,由此深受
到迎接,超级多等级次序都思索用MongoDB 来取代MySQL 等守旧数据库来达成不是特意复杂的
Web 应用。由于数据量实在太大,所以迁移到了MongoDB 上边,数据查询的速度获得了非
常分明的进级换代。
下面将介绍一些尖端查询语法:
5.1 条件操作符
5.1 条件操作符
<, <=, >, >= 那个操作符就不要多解释了,最常用也是最轻松易行的
db.collection.find({ "field" : { $gt: value } } ); // 大于: field > value
db.collection.find({ "field" : { $lt: value } } ); // 小于: field < value
db.collection.find({ "田野" : { $gte: value } } ); // 大于等于: 田野先生>= value
db.collection.find({ "田野先生" : { $lte: value } } ); // 小于等于: 田野同志<= value
若果要同时满足多个条件,能够这么做
db.collection.find({ "field" : { $gt: value1, $lt: value2 } } ); // value1 < field < value
5.2 $all相称全部
其风流浪漫操作符跟SQL 语法的in 近似,但不一样的是, in 只需满意( )内的某贰个值就可以, 而$all 必
须满足[ ]内的装有值,比方:
db.users.find({age : {$all : [6, 8]}});
能够查询出 {name: '大卫', age: 26, age: [ 6, 8, 9 ] }
但查询不出 {name: '大卫', age: 26, age: [ 6, 7, 9 ] }
5.3 $exists剖断字段是或不是存在
询问全部存在age 字段的记录
db.users.find({age: {$exists: true}});
查询全体不设有name 字段的笔录
db.users.find({name: {$exists: false}});
比世尊讲如下:
C1 表的数额如下:
> db.c1.find();
{ "_id" : ObjectId("4fb4a773afa87dc1bed9432d"), "age" : 20, "length" : 30 }
{ "_id" : ObjectId("4fb4a7e1afa87dc1bed9432e"), "age_1" : 20, "length_1" : 30 }

29 / 91
询问存在字段age 的数据
> db.c1.find({age:{$exists:true}});
{ "_id" : ObjectId("4fb4a773afa87dc1bed9432d"), "age" : 20, "length" : 30 }
能够见到只呈现出了有age 字段的数码,age_1 的多少并不曾显得出来
5.4 Null值处理
Null 值的拍卖多少有好几意外,具体看上面包车型客车样例数据爬山涉水
> db.c2.find()
{ "_id" : ObjectId("4fc34bb81d8a39f01cc17ef4"), "name" : "Lily", "age" : null }
{ "_id" : ObjectId("4fc34be01d8a39f01cc17ef5"), "name" : "Jacky", "age" : 23 }
{ "_id" : ObjectId("4fc34c1e1d8a39f01cc17ef6"), "name" : "Tom", "addr" : 23 }
里面”Lily”的age 字段为空,汤姆 未有age 字段,大家想找到age 为空的行,具体如下爬山涉水
> db.c2.find({age:null})
{ "_id" : ObjectId("4fc34bb81d8a39f01cc17ef4"), "name" : "Lily", "age" : null }
{ "_id" : ObjectId("4fc34c1e1d8a39f01cc17ef6"), "name" : "Tom", "addr" : 23 }
古怪的是我们认为只好找到”Lily”,但”汤姆”也被寻觅来了,所以”null”不只好找到它自己,
连不真实age 字段的笔录也寻找来了。那么什么样能力只找到”Lily”呢?大家用exists 来界定
须臾就可以:
> db.c2.find({age:{"$in":[null], "$exists":true}})
{ "_id" : ObjectId("4fc34bb81d8a39f01cc17ef4"), "name" : "Lily", "age" : null }
这么如作者辈盼望同样,唯有”Lily”被寻找来了。
5.5 $mod取模运算
查询age 取模10 等于0 的数据
db.student.find( { age: { $mod : [ 10 , 1 ] } } )
举个例子如下:
C1 表的数量如下:
> db.c1.find()
{ "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }
查询age 取模6 等于1 的数据
> db.c1.find({age: {$mod : [ 6 , 1 ] } })
{ "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }
能够看见只呈现出了age 取模6 等于1 的多少,其余不适合准则的多寡并不曾显得出来

30 / 91
5.6 $ne不等于
查询x 的值不对等3 的数码
db.things.find( { x : { $ne : 3 } } );
比方来讲如下:
C1 表的数据如下:
> db.c1.find()
{ "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }
查询age 的值不等于7 的数码
> db.c1.find( { age : { $ne : 7 } } );
{ "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }
能够看来只突显出了age 等于7 的多寡,此外不合乎法规的数据并不曾呈现出来
5.7 $in包含
mongoDB配制及学习。与sql 标准语法的用处是千篇一律的,即要查询的是风度翩翩多重枚举值的约束内
查询x 的值在2,4,6 限量内的数目
db.things.find({x:{$in: [2,4,6]}});
例如如下:
C1 表的数目如下:
> db.c1.find()
{ "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }
查询age 的值在7,8 范围内的多少
> db.c1.find({age:{$in: [7,8]}});
{ "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }
能够观看只呈现出了age 等于7 或8 的数目,另外不切合准绳的数码并不曾呈现出来
5.8 $nin不包含
与sql 规范语法的用处是千篇一律的,即要查询的数量留意气风发多元枚举值的界定外
查询x 的值在2,4,6 限量外的多少
db.things.find({x:{$nin: [2,4,6]}});
譬释迦牟尼讲如下:

31 / 91
C1 表的数目如下:
> db.c1.find()
{ "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }
查询age 的值在7,8 范围外的多少
> db.c1.find({age:{$nin: [7,8]}});
{ "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }
能够观察只浮现出了age 不对等7 或8 的数目,其余不契合法规的数码并不曾显得出来
5.9 $size数组成分个数
对于{name: 'David', age: 26, favorite_number: [ 6, 7, 9 ] }记录
匹配db.users.find({favorite_number: {$size: 3}});
不匹配db.users.find({favorite_number: {$size: 2}});
举个例子来讲如下:
C1 表的数额如下:
> db.c1.find()
{ "_id" : ObjectId("4fb4af85afa87dc1bed94330"), "age" : 7, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af89afa87dc1bed94331"), "age" : 8, "length_1" : 30 }
{ "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }
查询age 的值在7,8 范围外的数据
> db.c1.find({age:{$nin: [7,8]}});
{ "_id" : ObjectId("4fb4af8cafa87dc1bed94332"), "age" : 6, "length_1" : 30 }
能够看出只突显出了age 不等于7 或8 的数额,另外不合乎规则的多少并从未显得出来
5.10 正则表达式相称
询问不相称name=B*起头的笔录
db.users.find({name: {$not: /^B.*/}});
比喻如下:
C1 表的数量如下:
> db.c1.find();
{ "_id" : ObjectId("4fb5faaf6d0f9d8ea3fc91a8"), "name" : "Tony", "age" : 20 }
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }
询问name 不以T 起始的数额
> db.c1.find({name: {$not: /^T.*/}});
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }
能够看看只呈现出了name=托尼 的数据,另外不契合法则的数量并不曾体现出来

32 / 91
5.11 Javascript查询和$where查询
查询a 大于3 的数额,上边包车型客车查询格局万变不离其宗
db.c1.find( { a : { $gt: 3 } } );
db.c1.find( { $where: "this.a > 3" } );
db.c1.find("this.a > 3");
f = function() { return this.a > 3; } db.c1.find(f);
5.12 count查询记录条数
count 查询记录条数
db.users.find().count();
以下重回的不是5,而是user 表中颇有的记录数据
db.users.find().skip(10).limit(5).count();
假若要赶回约束之后的笔录数据,要接受count(true)或许count(非0)
db.users.find().skip(10).limit(5).count(true);
比方如下:
C1 表的数据如下:
> db.c1.find()
{ "_id" : ObjectId("4fb5faaf6d0f9d8ea3fc91a8"), "name" : "Tony", "age" : 20 }
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }
查询c1 表的数据量
> db.c1.count()
2
能够看见表中国共产党有2 条数据
5.13 skip约束重返记录的起源
从第3 条记下初叶,重临5 条记下(limit 3, 5)
db.users.find().skip(3).limit(5);
比释迦牟尼说如下:
C1 表的数量如下:
> db.c1.find()
{ "_id" : ObjectId("4fb5faaf6d0f9d8ea3fc91a8"), "name" : "Tony", "age" : 20 }
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }
查询c1 表的第2 条数据
> db.c1.find().skip(1).limit(1)
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }
可以看出表中第2 条数据被展现了出来

33 / 91
5.14 sort排序
以年纪升序asc
db.users.find().sort({age: 1});
以年龄降序desc
db.users.find().sort({age: -1});
C1 表的数额如下:
> db.c1.find()
{ "_id" : ObjectId("4fb5faaf6d0f9d8ea3fc91a8"), "name" : "Tony", "age" : 20 }
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }
查询c1 表按age 升序排列
> db.c1.find().sort({age: 1});
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }
{ "_id" : ObjectId("4fb5faaf6d0f9d8ea3fc91a8"), "name" : "Tony", "age" : 20 }
第1 条是age=10 的,而后升序排列结果集
查询c1 表按age 降序排列
> db.c1.find().sort({age: -1});
{ "_id" : ObjectId("4fb5faaf6d0f9d8ea3fc91a8"), "name" : "Tony", "age" : 20 }
{ "_id" : ObjectId("4fb5fab96d0f9d8ea3fc91a9"), "name" : "Joe", "age" : 10 }
第1 条是age=20 的,而后降序排列结果集
5.2 游标
象大超级多数据库产品相近,MongoDB 也是用游标来循环管理每一条结果数据,具体语法如
下:
> for( var c = db.t3.find(); c.hasNext(); ) {
... printjson( c.next());
... }
{ "_id" : ObjectId("4fb8e4838b2cb86417c9423a"), "age" : 1 }
{ "_id" : ObjectId("4fb8e4878b2cb86417c9423b"), "age" : 2 }
{ "_id" : ObjectId("4fb8e4898b2cb86417c9423c"), "age" : 3 }
{ "_id" : ObjectId("4fb8e48c8b2cb86417c9423d"), "age" : 4 }
{ "_id" : ObjectId("4fb8e48e8b2cb86417c9423e"), "age" : 5 }
MongoDB 还会有另大器晚成种办法来管理游标
> db.t3.find().forEach( function(u) { printjson(u); } );
{ "_id" : ObjectId("4fb8e4838b2cb86417c9423a"), "age" : 1 }
{ "_id" : ObjectId("4fb8e4878b2cb86417c9423b"), "age" : 2 }
{ "_id" : ObjectId("4fb8e4898b2cb86417c9423c"), "age" : 3 }
{ "_id" : ObjectId("4fb8e48c8b2cb86417c9423d"), "age" : 4 }

34 / 91
{ "_id" : ObjectId("4fb8e48e8b2cb86417c9423e"), "age" : 5 }
>
5.3 存款和储蓄进度
MongoDB 为无数主题材料提供了大器晚成层层的应用方案,针对于其余数据库的特征,它如故毫不示
弱,表现的非同凡响。
MongoDB 相像支撑存款和储蓄进程。关于存款和储蓄进度你需求知道的首先件事就是它是用javascript 来
写的。可能那会让您很古怪,为啥它用javascript 来写,但其实它会令你可怜安适,
MongoDB 存款和储蓄进程是积存在db.system.js 表中的,大家想像叁个粗略的sql 自定义函数如下爬山涉水
function addNumbers( x , y ) {
return x + y;
}
下边大家将以此sql 自定义函数转变为MongoDB 的积存进程:
> db.system.js.save({_id:"addNumbers", value:function(x, y){ return x + y; }});
积攒进程可以被查看,改进和删除,所以大家用find 来查阅一下是或不是那么些蕴藏进程已经被
开创上了。
> db.system.js.find()
{ "_id" : "addNumbers", "value" : function cf__1__f_(x, y) {
return x + y;
} }
>
与上述同类看起来可以选拔,上面小编看来实际调用一下以此蕴藏进度:
> db.eval('addNumbers(3, 4.2)');
7.2
>
如此的操作方法简直太轻松了,只怕那正是MongoDB 的吸重力所在。
db.eval()是一个比较奇异的事物,大家能够将储存进程的逻辑直接在中间并还要调用,而无
需事先评释存款和储蓄进程的逻辑。
> db.eval( function() { return 3+3; } );
6
>
从地点能够观看,MongoDB 的存放进程能够实惠的做到算术运算,但任何数据库产品在存
储进度中能够拍卖数据库内部的局地事务,例如抽取某张表的数据量等等操作,这一个
MongoDB 能不负职务呢?答案是大势所趋的,MongoDB 能够轻巧的姣好,看上面包车型地铁实例吧:
> db.system.js.save({_id:"get_count", value:function(){ return db.c1.count(); }});
> db.eval('get_count()')
2

35 / 91
能够看到仓库储存进度能够很自在的在仓库储存进程中操作表
第六章 Capped Collection
6.1 简要介绍
capped collections 是性质杰出的具有固定大小的汇聚,以LRU(Least Recently Used 最近起码
动用)法则和插入顺序进行age-out(老化移出)管理,自动体贴集结中指标的插入顺序,在创
建时要预先内定大小。如若空间用完,新加上的靶子将会代替会集中最旧的对象。
6.2 作用特色
能够插入及创新,但立异无法超过collection 的高低,否则更新失利。不容许删除,但是可
以调用drop() 删除集结中的全体行,可是drop 后须要显式地重新建立集结。在三十一位机上,黄金年代
个capped collection 的最大值约为482.5M,六拾个人上只受系统文件大小的范围。
6.3 常见用处
1、 logging
MongoDB 中国和东瀛记机制的首推,MongoDB 未有动用日志文件,而是把日志事件存款和储蓄在数
据库中。在贰个从未有过索引的capped collection 中插入对象的进度与在文件系统中记录日
志的进程非常。
2、 cache
缓存一些目的在数据库中,比方总结出来的总括消息。那样的须求在collection 上树立
七个索引,因为运用缓存往往是读比写多。
3、 auto archiving
能够应用capped collection 的age-out 个性,省去了写cron 脚本进行人工归档的行事。
6.4 推荐用法
1、 为了发挥capped collection 的最大质量,假使写比读多,最佳不用在上边建索引,不然
插入速度从"log speed"降为"database speed"。
2、使用"nature ordering"能够有效地搜索最近布置的要素,因为capped collection 能够确认保障
理当如此排序正是插入时的逐风度翩翩,相近于log 文件上的tail 操作。
6.5 注意事项
1、能够在成立capped collection 时内定collection 中能够寄放的最大文档数。但那时也要指
定size,因为三回九转先反省size 后检查maxRowNumber。能够采纳validate()查看贰个collection

36 / 91
生龙活虎度接纳了不怎么空间,从而调控size 设为多大。如爬山涉水
db.createCollection("mycoll", {capped:true, size:100000, max:100});
db.mycoll.validate();
max=1 时会往collection 中存放尽量多的documents。
2 、上述的createCollection 函数也得以用来成立日常的collection , 还应该有叁个参数
"autoIndexID",值可感到"true"和"false"来调控是或不是供给在"_id"字段上活动创造索引,如跋山涉水的近义词
db.createCollection("mycoll", {size:10000000, autoIndexId:false})。
暗许情况下对日常的collection 是开创索引的,但不会对capped collection 创设。
第七章 GridFS
GridFS 是如火如荼种将大型文件存储在MongoDB 数据库中的文件标准。全体官方扶助的驱动均实
现了GridFS 规范。
7.1 为啥要用GridFS
鉴于MongoDB 中BSON 对象大小是有节制的,所以GridFS 标准提供了风度翩翩种透明的机制,可
以将贰个大文件分割成为八个十分小的文书档案,那样的体制允许大家有效的保存大文件对象,特
别对于这个庞大的文书,比如录像、高清图片等。
7.2 如何实现海量存款和储蓄
为贯彻这一点,该职业内定了二个将文件分块的正规。各个文件都就要文件集结对象中保存后生可畏
个元数据对象,八个或八个chunk 块对象可被重新组合保存在三个chunk 块集结中。大好些个情景
下,你无需询问此标准中细节,而可将集中力放在各种语言版本的驱动中关于GridFS API 的
局部或许怎么着使用mongofiles 工具上。
7.3 语言辅助
GridFS 对Java, Perl, PHP, Python, Ruby 等程序语言均帮助,且提供了理想的API 接口。
7.4 简介
GridFS 使用三个表来存储数据爬山涉水
files 包蕴元数据对象
chunks 富含其余部分相关音信的二进制块
为了使三个GridFS 命名称叫叁个单龙腾虎跃的数据库,文件和块都有叁个前缀,暗中认可情形下,前缀
是fs,所以任何默许的GridFS 存款和储蓄将包蕴取名空间fs.files 和fs.chunks。各样第三方语言的
使得有权力改造那一个前缀,所以你能够尝试设置另四个GridFS 命名空间用于存款和储蓄照片,它
的具体地方为:photos.files 和photos.chunks。下边大家看一下实在的例子吗。

37 / 91
7.5 命令行工具
mongofiles 是从命令行操作GridFS 的豆蔻梢头种工具,举个例子大家将”mongosniff”这么些文件存到Curry
面,具体用法如下爬山涉水
[root@localhost bin]# ./mongofiles put testfile
connected to: 127.0.0.1
added file: { _id: ObjectId('4fc60175c714c5d960fff76a'), filename: "testfile", chunkSize: 262144,
uploadDate: new Date(1338376565745), md5: "8addbeb77789ae6b2cb75deee30faf1a", length:
16 }
done!
下边大家查一下看Curry有何样GridFS 文件,在”mongofiles”后加三个参数”list”就可以
[root@localhost bin]# ./mongofiles list
connected to: 127.0.0.1
testfile 16
接下去我们进Curry看一下是还是不是有新的东西
[root@localhost bin]# ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> show collections
fs.chunks --上文提到的fs.chunks
fs.files --上文提到的fs.files
system.indexes
system.js
>
咱俩后续查看fs.files 中的内容
> db.fs.files.find()
{ "_id" : ObjectId("4fc60175c714c5d960fff76a"), "filename" : "testfile", "chunkSize" : 262144,
"uploadDate" : ISODate("2012-05-30T11:16:05.745Z"), "md5" :
"8addbeb77789ae6b2cb75deee30faf1a", "length" : 16 }
字段表明:
Filename: 存款和储蓄的文书名
chunkSize: chunks 分块的轻重
uploadDate: 入库时间
md5: 此文件的md5 码
length: 文件大小, 单位”字节”
因此看来fs.files 中积存的是有个别基础的元数据音讯
我们继续查看fs.chunks 中的内容
> db.fs.chunks.find()
{ "_id" : ObjectId("4fc60175cf1154905d949336"), "files_id" :

38 / 91
ObjectId("4fc60175c714c5d960fff76a"), "n" : 0, "data" :
BinData(0,"SGVyZSBpcyBCZWlqaW5nCg==") }
里头比较关键的字段是”n”,它表示的是chunks 的序号,此序号从0 初始,看来fs.chunks
中蕴藏的是一些事实上的内容数据音讯
咱俩即然能将此文件存进去,大家就应有有措施将其收取来,下边看一下实例:
[root@localhost bin]# rm testfile
rm跋山涉水的近义词是还是不是删除 通常文件 “testfile”? y --先删文件
[root@localhost bin]# ./mongofiles get testfile --将其从Curry收取来
connected to: 127.0.0.1
done write to: testfile
[root@localhost bin]# md5sum testfile --校验md5,结果跟库里平等
8addbeb77789ae6b2cb75deee30faf1a testfile
[root@localhost bin]#
7.6 索引
db.fs.chunks.ensureIndex({files_id:1, n:1}, {unique: true});
与此相类似,一个块就能够应用它的files_id 和 n 的值实行寻觅。注意,GridFS 依然能够用findOne
获取第3个块,如下爬山涉水
db.fs.chunks.findOne({files_id: myFileID, n: 0});
第八章 MapReduce
MongoDB 的MapReduce 相当于Mysql 中的"group by",所以在MongoDB 上使用 Map/Reduce
拓宽并行"总括"十分轻巧。
运用MapReduce 要落到实处多个函数 Map 函数和Reduce 函数,Map 函数调用emit(key, value),
遍历collection中存有的笔录,将key与value传递给Reduce 函数实行拍卖。Map函数和Reduce
函数能够行使JavaScript 来兑现,能够经过db.runCommand 或mapReduce 命令来试行三个
MapReduce 的操作:
db.runCommand(
{ mapreduce : <collection>,
map : <mapfunction>,
reduce : <reducefunction>
[, query : <query filter object>]
[, sort : <sorts the input objects using this key. Useful for optimization, like sorting by the
emit key for fewer reduces>]
[, limit : <number of objects to return from collection>]
[, out : <see output options below>]

39 / 91
[, keeptemp: <true|false>]
[, finalize : <finalizefunction>]
[, scope : <object where fields go into javascript global scope >]
[, verbose : true]
}
);
参数表明:
mapreduce: 要操作的指标会集。
map: 映射函数 (生成键值对队列,作为 reduce 函数参数)。
reduce: 总括函数。
query: 指标志录过滤。
sort: 指标识录排序。
limit: 约束指标识录数据。
out: 总结结果寄存集结 (不钦点则运用有时集合,在顾客端断开后自行删除)。
keeptemp: 是还是不是保留有的时候集合。
finalize: 最后处理函数 (对 reduce 重返结果开展最后整理后存入结果集结)。
scope: 向 map、reduce、finalize 导入外界变量。
verbose: 展现详细的时日总括消息。
上边大家先希图一些多少:
> db.students.insert({classid:1, age:14, name:'Tom'})
> db.students.insert({classid:1, age:12, name:'Jacky'})
> db.students.insert({classid:2, age:16, name:'Lily'})
> db.students.insert({classid:2, age:9, name:'Tony'})
> db.students.insert({classid:2, age:19, name:'Harry'})
> db.students.insert({classid:2, age:13, name:'Vincent'})
> db.students.insert({classid:1, age:14, name:'Bill'})
> db.students.insert({classid:2, age:17, name:'Bruce'})
>
接下去,大家将演示怎么着计算1 班和2 班的学子数量
8.1 Map
Map 函数必需调用 emit(key, value) 再次来到键值对,使用 this 访谈当前待管理的 Document。
> m = function() { emit(this.classid, 1) }
function () {
emit(this.classid, 1);
}
>
value 能够采用 JSON Object 传递 (扶持七个属性值)。举例:
emit(this.classid, {count:1})

40 / 91
8.2 Reduce
Reduce 函数接纳的参数相近 Group 效果,将 Map 重回的键值体系组合成 { key, [value1,
value2, value3, value...] } 传递给 reduce。
> r = function(key, values) {
... var x = 0;
... values.forEach(function(v) { x += v });
... return x;
... }
function (key, values) {
var x = 0;
values.forEach(function (v) {x += v;});
return x;
}
>
Reduce 函数对这几个 values 进行 "总结" 操作,重返结果能够使用 JSON Object。
8.3 Result
> res = db.runCommand({
... mapreduce:"students",
... map:m,
... reduce:r,
... out:"students_res"
... });
{
"result" : "students_res",
"timeMillis" : 1587,
"counts" : {
"input" : 8,
"emit" : 8,
"output" : 2
},
"ok" : 1
}
> db.students_res.find()
{ "_id" : 1, "value" : 3 }
{ "_id" : 2, "value" : 5 }
>
mapReduce() 将结果存款和储蓄在 "students_res" 表中。

41 / 91
8.4 Finalize
动用 finalize() 大家得以对 reduce() 的结果做进一步管理。
> f = function(key, value) { return {classid:key, count:value}; }
function (key, value) {
return {classid:key, count:value};
}
>
咱俩再另行总结一遍,看看重临的结果:
> res = db.runCommand({
... mapreduce:"students",
... map:m,
... reduce:r,
... out:"students_res",
... finalize:f
... });
{
"result" : "students_res",
"timeMillis" : 804,
"counts" : {
"input" : 8,
"emit" : 8,
"output" : 2
},
"ok" : 1
}
> db.students_res.find()
{ "_id" : 1, "value" : { "classid" : 1, "count" : 3 } }
{ "_id" : 2, "value" : { "classid" : 2, "count" : 5 } }
>
列名变与 “classid”和”count”了,那样的列表更易于通晓。
8.5 Options
作者们还是能增进更加的多的操纵细节。
> res = db.runCommand({
... mapreduce:"students",
... map:m,
... reduce:r,
... out:"students_res",
... finalize:f,
... query:{age:{$lt:10}}
... });

42 / 91
{
"result" : "students_res",
"timeMillis" : 358,
"counts" : {
"input" : 1,
"emit" : 1,
"output" : 1
},
"ok" : 1
}
> db.students_res.find();
{ "_id" : 2, "value" : { "classid" : 2, "count" : 1 } }
>
可以阅览先实行了过滤,只取age<10 的数目,然后再扩充总括,所以就未有1 班的总括数
据了。
其三有个别 处理篇
第九歌 数据导出 mongoexport
用作DBA,平日会遇见导入导出数据的供给,下边就介绍实用工具mongoexport 和
mongoimport 的选取方式,望你会持有收获。
要是Curry有一张user 表,里面有2 条记下,大家要将它导出
> use my_mongodb
switched to db my_mongodb
> db.user.find();
{ "_id" : ObjectId("4f81a4a1779282ca68fd8a5a"), "uid" : 2, "username" : "Jerry", "age" : 100 }
{ "_id" : ObjectId("4f844d1847d25a9ce5f120c4"), "uid" : 1, "username" : "Tom", "age" : 25 }
>
9.1 常用导出谋献策
[root@localhost bin]# ./mongoexport -d my_mongodb -c user -o user.dat
connected to: 127.0.0.1
exported 2 records
[root@localhost bin]# cat user.dat
{ "_id" : { "$oid" : "4f81a4a1779282ca68fd8a5a" }, "uid" : 2, "username" : "Jerry", "age" : 100 }
{ "_id" : { "$oid" : "4f844d1847d25a9ce5f120c4" }, "uid" : 1, "username" : "Tom", "age" : 25 }
[root@localhost bin]#
参数表达:
-d 指明使用的库, 本例中为” my_mongodb”

43 / 91
-c 指明要导出的表, 本例中为”user”
-o 指明要导出的文本名, 本例中为”user.dat”
从地点能够观察导出的章程采纳的是JSON 的样式
9.2 导出CSV格式的文书
[root@localhost bin]# ./mongoexport -d my_mongodb -c user --csv -f uid,username,age -o
user_csv.dat
connected to: 127.0.0.1
exported 2 records
[root@localhost bin]# cat user_csv.dat
uid,username,age
2,"Jerry",100
1,"Tom",25
[root@localhost bin]#
参数表达:
-csv 指要要导出为csv 格式
-f 指明须要导出哪些例
更详细的用法能够 mongoexport –help 来查看
第十章 数据导入mongoimport
在上例中大家商讨的是导出工具的接纳,那么本节将研究什么向表中程导弹入数据
10.1 导入JSON 数据
咱俩先将表user 删除掉,以便演示效果
> db.user.drop();
true
> show collections;
system.indexes
>
下一场导入数据
[root@localhost bin]# ./mongoimport -d my_mongodb -c user user.dat
connected to: 127.0.0.1
imported 2 objects
[root@localhost bin]#
能够见见导入数据的时候会隐式创制表结构

44 / 91
10.2 导入CSV数据
咱俩先将表user 删除掉,以便演示效果
> db.user.drop();
true
> show collections;
system.indexes
>
然后导入数据
[root@localhost bin]# ./mongoimport -d my_mongodb -c user --type csv --headerline --file
user_csv.dat
connected to: 127.0.0.1
imported 3 objects
[root@localhost bin]#
参数表明:
-type 指明要导入的文件格式
-headerline 批明不导入第后生可畏行,因为第生机勃勃行是列名
-file 指明要导入的公文路线
注意:
CSV 格式卓绝,主流数据库都协理导出为CSV 的格式,所以这种格式特别平价异构数据迁移
第十生机勃勃章 数据备份mongodump
可以用mongodump 来做MongoDB 的库或表级其他备份,上边比方表明:
备份my_mongodb 数据库
[root@localhost bin]# ./mongodump -d my_mongodb
connected to: 127.0.0.1
DATABASE: my_mongodb to dump/my_mongodb
my_mongodb.system.indexes to dump/my_mongodb/system.indexes.bson
1 objects
my_mongodb.user to dump/my_mongodb/user.bson
2 objects
[root@localhost bin]# ll
总计 67648
-rwxr-xr-x 1 root root 7508756 2011-04-06 bsondump
drwxr-xr-x 3 root root 4096 04-10 23:54 dump
-rwxr-xr-x 1 root root 2978016 2011-04-06 mongo
那儿会在当前目录下创办叁个dump 目录,用于寄存备份出来的文本
也足以钦赐备份寄存的目录,

45 / 91
[root@localhost bin]# ./mongodump -d my_mongodb -o my_mongodb_dump
connected to: 127.0.0.1
DATABASE: my_mongodb to my_mongodb_dump/my_mongodb
my_mongodb.system.indexes to
my_mongodb_dump/my_mongodb/system.indexes.bson
1 objects
my_mongodb.user to my_mongodb_dump/my_mongodb/user.bson
2 objects
[root@localhost bin]#
本条例子中将备份的公文存在了当前目录下的my_mongodb_dump 目录下
第十八章 数据复苏mongorestore
由刘恒好已经做了备份,所以大家先将库my_mongodb 删除掉
> use my_mongodb
switched to db my_mongodb
> db.dropDatabase()
{ "dropped" : "my_mongodb", "ok" : 1 }
> show dbs
admin (empty)
local (empty)
test (empty)
>
接下去大家进行数据库苏醒
[root@localhost bin]# ./mongorestore -d my_mongodb my_mongodb_dump/*
connected to: 127.0.0.1
Wed Apr 11 00:03:03 my_mongodb_dump/my_mongodb/user.bson
Wed Apr 11 00:03:03 going into namespace [my_mongodb.user]
Wed Apr 11 00:03:03 2 objects found
Wed Apr 11 00:03:03 my_mongodb_dump/my_mongodb/system.indexes.bson
Wed Apr 11 00:03:03 going into namespace [my_mongodb.system.indexes]
Wed Apr 11 00:03:03 { name: "_id_", ns: "my_mongodb.user", key: { _id: 1 }, v: 0 }
Wed Apr 11 00:03:03 1 objects found
[root@localhost bin]#
经求证数据库又回来了,其实假若想重温旧业库,也大可不必先删除my_mongodb 库,只要指
明 –drop 参数,就足以在平复的时候先删除表然后再向表中插入数据的
第十一章 访谈调节
合法手册中运维 MongoDB 服务时并未有其他参数,意气风发旦客商端连接后方可对数据库任意操

46 / 91
作,而且能够远程访谈数据库,所以推举开荒阶段能够不安装任何参数,但对于生产条件还
是要紧凑思虑一下安全方面包车型大巴成分,而升高 MongoDB 数据库安全有多少个地点爬山涉水
绑定IP 内网地址访谈MongoDB 服务
安装监听端口
使用顾客名和口令登录
13.1 绑定IP内网地址访谈MongoDB服务
MongoDB 能够节制只允许某风流倜傥特定IP 来访谈,只要在运行时加二个参数bind_ip 即可,如
下:
服务端限定独有192.168.1.103 这些IP 能够访问MongoDB 服务
[root@localhost bin]# ./mongod --bind_ip 192.168.1.103
客户端访谈时要求明显内定服务端的IP,不然会报错:
[root@localhost bin]# ./mongo 192.168.1.102
MongoDB shell version: 1.8.1
connecting to: 192.168.1.103/test
>
13.2 设置监听端口
合法暗许的监听端口是27017,为了安全起见,平日都会改正那么些监听端口,防止恶意的连
接尝试,具体如下爬山涉水
将服务端监听端口修正为28018
[root@localhost bin]# ./mongod --bind_ip 192.168.1.103 --port 28018
端户访谈时不内定端口,会连接到暗许端口27017,对于本例会报错
[root@localhost bin]# ./mongo 192.168.1.102
MongoDB shell version: 1.8.1
connecting to: 192.168.1.102/test
Sun Apr 15 15:55:51 Error: couldn't connect to server 192.168.1.102 shell/mongo.js:81
exception: connect failed
为此当服务端钦命了端口后,客户端必定要明了钦赐端口才足以健康访问
[root@localhost bin]# ./mongo 192.168.1.102:28018
MongoDB shell version: 1.8.1
connecting to: 192.168.1.102:28018/test
>
13.3 使用客商名和口令登陆
MongoDB 暗中认可的开发银行是不表达用户名和密码的,运营MongoDB 后,能够直接用MongoDB 连接

47 / 91
上去,对具备的库具有root 权限。所以运维的时候钦命参数,能够阻挡客商端的拜访和接二连三。
先启用系统的记名验证模块, 只需在运行时钦点 auth 参数就可以,如:
[root@localhost bin]# ./mongod --auth
地面客户端连接一下探问效果;
[root@localhost bin]# ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> show collections;
>
很想得到,为何大家启用了登陆验证模块,但大家登入前卫未点名客商,为何仍然为能够登陆
啊?在最先叶的时候 MongoDB 都私下认可有一个 admin 数据库(私下认可是空的),
而 admin.system.users 中校会保存比在别的数据库中安装的客商权限更大的客商音讯。
注意爬山涉水当 admin.system.users 中没有增加任何顾客时,纵然 MongoDB 运维时增加了 --auth
参数,假使在除 admin 数据库中加多了客商,此时不开展此外申明还能动用其他操作,
直至知道你在 admin.system.users 中增多了一个顾客。
1、创立类别root顾客
在admin 库中新添八个顾客root:
[root@localhost bin]# ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> db.addUser("root","111")
{
"user" : "root",
"readOnly" : false,
"pwd" : "e54950178e2fa777b1d174e9b106b6ab"
}
> db.auth("root","111")
1
>
地面顾客端连接,但不点名顾客,结果如下:
[root@localhost bin]# ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> show collections;
Sun Apr 15 16:36:52 uncaught exception: error: {
"$err" : "unauthorized db:test lock type:-1 client:127.0.0.1",
"code" : 10057
}
>
连上test 库了,但特别操作时有十分,看来MongoDB 允许未授权连接,不能够扩充其余

48 / 91
地点顾客端连接,钦赐客商,结果如下:
[root@localhost bin]# ./mongo -u root -p
MongoDB shell version: 1.8.1
Enter password:
connecting to: test
> show collections;
system.indexes
system.users
>
总的来说内定了客商名之后,访谈数据库才是正规
2、创设钦定权限客商
MongoDB 也支撑为某些特定的数据库来安装客户,如大家为test 库设三个只读的客商
user_reader:
[root@localhost bin]# ./mongo -u root -p
MongoDB shell version: 1.8.1
Enter password:
connecting to: test
> show collections;
system.indexes
system.users
> use test
switched to db test
> db.addUser("user_reader", "user_pwd", true)
{
"user" : "user_reader",
"readOnly" : true,
"pwd" : "0809760bb61ee027199e513c5ecdedc6"
}
>
客商端用此客户来拜会:
[root@localhost bin]# ./mongo -u user_reader -p
MongoDB shell version: 1.8.1
Enter password:
connecting to: test
> show collections;
system.indexes
system.users
>

49 / 91
第十三章 命令行操作
MongoDB shell 不止是贰个交互式的shell,它也支撑实行内定javascript 文件,也扶持施行
点名的一声令下片断。
有了这几个个性,就足以将MongoDB 与linux shell 完美结合,实现一大半的日常性管理和保安
工作。
14.1 通过eval参数实施钦定语句
比如,需求查询test 库的t1 表中的记录数有稍许,常用方法如下:
[root@localhost bin]# ./mongo test
MongoDB shell version: 1.8.1
connecting to: test
> db.t1.count()
7
>
透过命令行eval 参数直接执行语句:
[root@localhost bin]# ./mongo test --eval "printjson(db.t1.count())"
MongoDB shell version: 1.8.1
connecting to: test
7
14.2 实施钦赐文件中的内容
万一波及到超级多的操作后,能力获取结果,那么用eval 的艺术来做的话是不可能形成的,
那么更加灵活的实践钦点文件的办法就派上用场了。举个例子大家依旧要查阅test 库t1 表中的记
录数:
t1_count.js 正是大家要实施的文件,里面包车型客车内容如下
[root@localhost bin]# cat t1_count.js
var totalcount = db.t1.count();
printjson('Total count of t1 is : ' + totalcount);
printjson('-----------------------');
上边我们将进行那一个文件
[root@localhost bin]# ./mongo t1_count.js
MongoDB shell version: 1.8.1
connecting to: test
"Total count of t1 is : 7"
"-----------------------"

50 / 91
[root@localhost bin]#
世家能够看出最后赢得t1 表的记录数 7,那么有个别不要求的表达性文字大家假使不希望出
现该怎么办吧?
[root@localhost bin]# ./mongo --quiet t1_count.js
"Total count of t1 is : 7"
"-----------------------"
[root@localhost bin]#
经过点名quiet 参数,即能够将风姿罗曼蒂克部分登入音信屏蔽掉,那样能够让结果更清楚。
第十六章 进度调控
DBA 平时要化解系统的风度翩翩对查询质量难点,此时貌似的操作习于旧贯是先查看有怎么着进度,然后
将特别的长河杀掉,那么MongoDB 是如哪处理的吗?
15.1 查看活动进程
查阅活动进度,便于精晓系统正在做什么,以便做下一步推断
> db.currentOp();
> // 等同于: db.$cmd.sys.inprog.findOne()
{ inprog: [ { "opid" : 18 , "op" : "query" , "ns" : "mydb.votes" ,
"query" : "{ score : 1.0 }" , "inLock" : 1 }
]
}
字段表达:
Opid: 操作进度号
Op: 操作类型(查询,更新等)
Ns: 命名空间, 指操作的是哪位指标
Query: 要是操作类型是查询的话,这里将体现具体的询问内容
lockType: 锁的品类,指明是读锁照旧写锁
15.2 结束进度
比如有个别万分是出于有个别进度产生的,那么通常DBA 都会毫不留情的杀掉这么些元凶祸首的
进程,上边将是那操作
> db.killOp(1234/*opid*/)
> // 等同于: db.$cmd.sys.killop.findOne({op:1234})
注意:
不要kill 内部发起的操作,例如说replica set 发起的sync 操作等

51 / 91
第二盘部 质量篇
第十五章 索引
MongoDB 提供了三种性的目录支持,索引音信被保存在system.indexes 中,且暗中认可总是为_id
开创索引,它的目录使用基本和MySQL 等关系型数据库相仿。其实能够如此说说,索引是
超过于数据存款和储蓄系统之上的另龙马精气神层系统,所以各样组织迥异的积攒皆有同蒸蒸日上或通常的索引实
现及使用接口并不足为道。
16.1 基础索引
在字段age 上开创索引,1(升序);-1(降序)
> db.t3.ensureIndex({age:1})
> db.t3.getIndexes();
[
{
"name" : "_id_",
"ns" : "test.t3",
"key" : {
"_id" : 1
},
"v" : 0
},
{
"_id" : ObjectId("4fb906da0be632163d0839fe"),
"ns" : "test.t3",
"key" : {
"age" : 1
},
"name" : "age_1",
"v" : 0
}
]
>
上例显示出来的累加有2 个目录,个中_id 是创设表的时候自动创设的目录,此索引是不能够
够删除的。
当系统本来就有恢宏数目时,创立索引正是个特别耗费时间的活,大家能够在后台实施,只需点名
“backgroud:true”即可。
> db.t3.ensureIndex({age:1} , {backgroud:true})

52 / 91
16.2 文书档案索引
目录能够别的类型的字段,以至文档
db.factories.insert( { name: "wwl", addr: { city: "Beijing", state: "BJ" } } );
//在addr 列上创造索引
db.factories.ensureIndex( { addr : 1 } );
//下边那个查询将会用到大家正好确立的目录
db.factories.find( { addr: { city: "Beijing", state: "BJ" } } );
//但是下边这么些查询将不会用到目录,因为查询的依次跟索引建构的依次不相符
db.factories.find( { addr: { state: "BJ" , city: "Beijing"} } );
16.3 组合索引
跟其他数据库产品意气风发律,MongoDB 也会有结合索引的,上面大家将要addr.city 和addr.state
上树立整合索引。当创设组合索引时,字段前面包车型大巴1 代表升序,-1 表示降序,是用1 也许
用-1 首借使跟排序的时候或钦命范围内查询 的时候有关的。
db.factories.ensureIndex( { "addr.city" : 1, "addr.state" : 1 } );
// 下边包车型地铁查询都用到了那几个目录
db.factories.find( { "addr.city" : "Beijing", "addr.state" : "BJ" } );
db.factories.find( { "addr.city" : "Beijing" } );
db.factories.find().sort( { "addr.city" : 1, "addr.state" : 1 } );
db.factories.find().sort( { "addr.city" : 1 } )
16.4 独一索引
只需在ensureIndex 命令中钦定”unique:true”就能够创立独一索引。举例,往表t4 中插入2 条
记录
db.t4.insert({firstname: "wang", lastname: "wenlong"});
db.t4.insert({firstname: "wang", lastname: "wenlong"});
在t4 表中国建工业总集结团立独一索引
> db.t4.ensureIndex({firstname: 1, lastname: 1}, {unique: true});
E11000 duplicate key error index: test.t4.$firstname_1_lastname_1 dup key: { : "wang", :
"wenlong" }
能够看看,当建独一索引时,系统报了“表里有重复值”的错,具体原因便是因为表中有2
条一模一模的数额,所以构建不了独一索引。

53 / 91
16.5 强制行使索引
hint 命令能够强制行使有些索引。
> db.t5.insert({name: "wangwenlong",age: 20})
> db.t5.ensureIndex({name:1, age:1})
> db.t5.find({age:{$lt:30}}).explain()
{
"cursor" : "BasicCursor",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : { --并从未利用索引
}
}
> db.t5.find({age:{$lt:30}}).hint({name:1, age:1}).explain() --强制使用索引
{
"cursor" : "BtreeCursor name_1_age_1",
"nscanned" : 1,
"nscannedObjects" : 1,
"n" : 1,
"millis" : 1,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : { --被强制行使索引了
"name" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"age" : [

54 / 91
[
-1.7976931348623157e+308,
30
]
]
}
}
>
16.6 删除索引
删除索引分为删除某张表的具备索引和删除某张表的有个别索引,具体如下爬山涉水
//删除t3 表中的全部索引
db.t3.dropIndexes()
//删除t4 表中的firstname 索引
db.t4.dropIndex({firstname: 1})
第十四章 explain施行布署
MongoDB 提供了多个 explain 命令让大家获知系统如什么地区理查询央浼。利用 explain 命令,
小编们能够很好地观看系统如何使用索引来加速检索,同期能够针对优化索引。
> db.t5.ensureIndex({name:1})
> db.t5.ensureIndex({age:1})
> db.t5.find({age:{$gt:45}}, {name:1}).explain()
{
"cursor" : "BtreeCursor age_1",
"nscanned" : 0,
"nscannedObjects" : 0,
"n" : 0,
"millis" : 0,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"age" : [
[
45,
1.7976931348623157e+308
]
]

55 / 91
}
}
字段表达:
cursor: 重返游标类型(BasicCursor 或 BtreeCursor)
nscanned: 被扫描的文书档案数量
n: 重回的文书档案数量
millis: 耗时(毫秒)
indexBounds: 所使用的目录
第十一章 优化器profile
在MySQL 中,慢查询日志是时常作为我们优化数据库的基于,那在MongoDB 中是还是不是有相近
的作用吗?答案是一定的,那正是MongoDB Database Profiler。所以MongoDB 不独有有,并且
还会有大器晚成比较MySQL 的Slow Query Log 更详实的消息。
18.1 开启 Profiling 功能
有二种方式得以决定 Profiling 的按键和等级,第意气风发种是间接在起步参数里一向开展设置。
启动MongoDB 时加上–profile=级别 即可。
也足以在客商端调用db.setProfilingLevel(等级) 命令来实时配置,Profiler 新闻保存在
system.profile 中。大家得以经过db.getProfilingLevel()命令来收获当前的Profile 等第,近似如
下操作
> db.setProfilingLevel(2);
{ "was" : 0, "slowms" : 100, "ok" : 1 }
地点profile 的品级能够取0,1,2 四个值,他们表示的意义如下跋山涉水的近义词
0 – 不开启
1 – 记录慢命令 (默感到>100ms)
2 – 记录全数命令
Profile 记录在等级1 时会记录慢命令,那么那一个慢的定义是怎么?上面大家聊到其默认为
100ms,当然有私下认可就有设置,其设置方式和品级相通有二种,日新月异种是透过抬高–slowms 启
动参数配置。第二种是调用db.setProfilingLevel 时抬高首个参数跋山涉水的近义词
db.setProfilingLevel( level , slowms )
db.setProfilingLevel( 1 , 10 );
18.2 查询 Profiling 记录
与MySQL 的慢查询日志不相同,MongoDB Profile 记录是直接存在系统db 里的,记录地方
system.profile ,所以,大家假使查询那个Collection 的笔录就足以博得到大家的 Profile 记
录了。列出推行时间专长某如日方升限度(5ms)的 Profile 记录:
db.system.profile.find( { millis : { $gt : 5 } } )

56 / 91
翻开最新的 Profile 记录爬山涉水
db.system.profile.find().sort({$natural:-1}).limit(1)
> db.system.profile.find().sort({$natural:-1}).limit(1)
{ "ts" : ISODate("2012-05-20T16:50:36.321Z"), "info" : "query test.system.profile reslen:1219
nscanned:8 nquery: { query: {}, orderby: { $natural: -1.0 } } nreturned:8 bytes:1203", "millis" :
0 }
>
字段表明:
ts跋山涉水的近义词 该命令在曾几何时施行
info: 本命令的详细新闻
reslen: 再次回到结果集的轻重
nscanned: 本次查询扫描的记录数
nreturned: 本次查询实际重临的结果集
millis: 该命令实施耗时,以皮秒记
MongoDB Shell 还提供了一个相比精简的吩咐show profile,可列出近期5 条实施时间抢先
1ms 的 Profile 记录。
第十四章 质量优化
若是nscanned(扫描的记录数)远大于nreturned(重临结果的记录数)的话,那么大家将要怀念
经过加索引来优化记录定位了。
reslen 假设过大,那么评释大家回来的结果集太大了,那时请查看find 函数的第二个参数是
否只写上了你必要的属性名。
对此开创索引的提出是跋山涉水的近义词如果超少读,那么尽量不要增多索引,因为索引越来越多,写操作会越
慢。即使读量比不小,那么制造索引依然相比经济的。
要是大家依据时间戳查询近年来刊登的10 篇博客小说跋山涉水的近义词
articles = db.posts.find().sort({ts:-1});
for (var i=0; i< 10; i++) {
print(articles[i].getSummary());
}
19.1 优化方案1: 创制索引
在询问条件的字段上,也许排序条件的字段上开创索引,能够显明增进执行效用爬山涉水
db.posts.ensureIndex({ts:1});
19.2 优化方案2: 节制重返结果条数
动用limit()限制再次回到结果集的大大小小,能够减掉database server 的能源消耗,能够减小互联网传

57 / 91
输数据量。
articles = db.posts.find().sort({ts:-1}).limit(10);
19.3 优化方案3: 只询问利用到的字段,而不查询所有字段
在本例中,博客日志记录内容可能那些大,並且还包涵了评价内容(作为embeded 文书档案)。
就此只询问利用的字段,比查询全数字段效能越来越高爬山涉水
articles = db.posts.find({}, {ts:1,title:1,author:1,abstract:1}).sort({ts:-1}).limit(10);
在乎爬山涉水即使只询问部分字段的话,不可能用再次来到的对象直接更新数据库。上面包车型客车代码是荒唐的爬山涉水
a_post = db.posts.findOne({}, Post.summaryFields);
a_post.x = 3;
db.posts.save(a_post);
19.4 优化方案4: 接纳capped collection
capped Collections 比普通Collections 的读写作用高。Capped Collections 是高效能的Collection
项目,它犹如下特征跋山涉水的近义词
1、 固定大小;Capped Collections 必须事先创制,并设置大小跋山涉水的近义词
db.createCollection("mycoll", {capped:true, size:100000})
2、 Capped Collections 可以insert 和update 操作;不能delete 操作。只能用drop()方法
删除全部Collection。
3、 暗中认可基于Insert 的次第排序的。倘使查询时不曾排序,则连接遵照insert 的次第返回。
4、 FIFO。尽管胜过了Collection 的范围大小,则用FIFO 算法,新记录将代表最早insert 的
记录。
19.5 优化方案5: 选择Server Side Code Execution
Server-Side Processing 相符于SQL 数据库的积累进度,使用Server-Side Processing 能够减小网
络通讯的费用。
19.6 优化方案6: Hint
诚如意况下MongoDB query optimizer 都干活非凡,但有一点情状下利用hint()能够巩固操作效
率。Hint 能够强制要求查询操作使用有些索引。举例,假使要查询四个字段的值,如若在其
中贰个字段上有索引,能够动用hint跋山涉水的近义词
db.collection.find({user:u, foo:d}).hint({user:1});
19.7 优化方案7: 选择Profiling
Profiling 作用自然是会影响功用的,可是不太严重,原因是他运用的是system.profile 来记
录,而system.profile 是一个capped collection 这种collection 在操作上有点限量和特点,

58 / 91
唯独效用更加高。
第三十章 质量监察和控制
20.1 mongosniff
此工具得以从尾部监察和控制到底有啥样命令发送给了MongoDB 去实行,从当中就足以扩充解析爬山涉水
以root 身份施行爬山涉水
./mongosniff --source NET lo
接下来其会监督检查位到当地以localhost 监听暗许27017 端口的MongoDB 的具有包伏乞,如执
行”show dbs” 操作
[root@localhost bin]# ./mongo
MongoDB shell version: 1.8.1
connecting to: test
> show dbs
admin 0.0625GB
foo 0.0625GB
local (empty)
test 0.0625GB
>
那么你能够看见如下输出。
[root@localhost bin]# ./mongosniff --source NET lo
sniffing... 27017
127.0.0.1:38500 -->> 127.0.0.1:27017 admin.$cmd 60 bytes id:537ebe0f 1400815119
query: { whatsmyuri: 1 } ntoreturn: 1 ntoskip: 0
127.0.0.1:27017 <<-- 127.0.0.1:38500 78 bytes id:531c3855 1394358357 - 1400815119
reply n:1 cursorId: 0
{ you: "127.0.0.1:38500", ok: 1.0 }
127.0.0.1:38500 -->> 127.0.0.1:27017 admin.$cmd 80 bytes id:537ebe10 1400815120
query: { replSetGetStatus: 1, forShell: 1 } ntoreturn: 1 ntoskip: 0
127.0.0.1:27017 <<-- 127.0.0.1:38500 92 bytes id:531c3856 1394358358 - 1400815120
reply n:1 cursorId: 0
{ errmsg: "not running with --replSet", ok: 0.0 }
127.0.0.1:38500 -->> 127.0.0.1:27017 admin.$cmd 67 bytes id:537ebe11 1400815121
query: { listDatabases: 1.0 } ntoreturn: -1 ntoskip: 0
127.0.0.1:27017 <<-- 127.0.0.1:38500 293 bytes id:531c3857 1394358359 - 1400815121
reply n:1 cursorId: 0
{ databases: [ { name: "foo", sizeOnDisk: 67108864.0, empty: false }, { name: "test",
sizeOnDisk: 67108864.0, empty: false }, { name: "admin", sizeOnDisk: 67108864.0, empty: false },
{ name: "local", sizeOnDisk: 1.0, empty: true } ], totalSize: 201326592.0, ok: 1.0 }
127.0.0.1:38500 -->> 127.0.0.1:27017 admin.$cmd 80 bytes id:537ebe12 1400815122

59 / 91
query: { replSetGetStatus: 1, forShell: 1 } ntoreturn: 1 ntoskip: 0
127.0.0.1:27017 <<-- 127.0.0.1:38500 92 bytes id:531c3858 1394358360 - 1400815122
reply n:1 cursorId: 0
{ errmsg: "not running with --replSet", ok: 0.0 }
假如将这么些输出到三个日志文件中,那么就足以保留下全部数据库操作的历史记录,对于后
期的属性深入分析和日喀则审计等专门的学业将是叁个宏伟的进献。
20.2 Mongostat
此工具得以火速的查阅某组运营中的MongoDB 实例的总计消息,用法如下跋山涉水的近义词
[root@localhost bin]# ./mongostat
下边是实行结果(部分):
[root@localhost bin]# ./mongostat
insert query update delete ...... locked % idx miss % qr|qw ar|aw conn time
*0 *0 *0 *0 ...... 0 0 0|0 1|0 4 01:19:15
*0 *0 *0 *0 ...... 0 0 0|0 1|0 4 01:19:16
*0 *0 *0 *0 ...... 0 0 0|0 1|0 4 01:19:17
字段表达:
insert: 每秒插入量
query: 每秒查询量
update: 每秒更新量
delete: 每秒删除量
locked: 锁定量
qr | qw: 客商端查询排队长度(读|写)
ar | aw: 活跃客商端量(读|写)
conn: 连接数
time: 当前时刻
它每分钟刷新一回状态值,提供卓越的可读性,通过那么些参数能够洞察到叁个完璧归赵的质量情
况。
20.3 db.serverStatus
本条命令是最常用也是最基础的查阅实例运营状态的通令之豆蔻年华,上面大家看一下它的输出:
> db.serverStatus()
{
"host" : "localhost.localdomain",
"version" : "1.8.1", --服务器版本
"process" : "mongod",
"uptime" : 3184, --运营时间(秒)
"uptimeEstimate" : 3174,
"localTime" : ISODate("2012-05-28T11:20:22.819Z"),

60 / 91
"globalLock" : {
"totalTime" : 3183918151,
"lockTime" : 10979,
"ratio" : 0.000003448267034299149,
"currentQueue" : {
"total" : 0, --当前全方位队列量
"readers" : 0, --读诉求队列量
"writers" : 0 --写诉求队列量
},
"activeClients" : {
"total" : 0, --当前任何顾客端连接量
"readers" : 0, --客商端读央浼量
"writers" : 0 --顾客端写央浼量
}
},
"mem" : {
"bits" : 32, --32 位系统
"resident" : 20, --占用物量内部存款和储蓄器量
"virtual" : 126, --设想内存量
"supported" : true, --是或不是协助扩张内存
"mapped" : 32
},
"connections" : {
"current" : 1, --当前移动连接量
"available" : 818 --剩余空闲连接量
},
……
"indexCounters" : {
"btree" : {
"accesses" : 0, --索引被访问量
"hits" : 0, --索引命中量
"misses" : 0, --索引偏差量
"resets" : 0,
"missRatio" : 0 --索引偏差率(未命中率)
}
},
……
"network" : {
"bytesIn" : 1952, --发给此服务器的数据量(单位:byte)
"bytesOut" : 25744, --此服务器发出的数据量(单位:byte)
"numRequests" : 30 --发给此服务器的央求量
},
"opcounters" : {
"insert" : 0, --插入操作的量

61 / 91
"query" : 1, --查询操作的量
"update" : 0, --更新操作的量
"delete" : 0, --删除操作的量
"getmore" : 0,
"command" : 31 --另外操作的量
},
……
"ok" : 1
}
>
此工具提了相比详细的音信,以樱笋时经对根本的大器晚成对参数做了表达,请大家仿效。、
20.4 db.stats
db.stats 查看数据库状态消息。使用样举例下:
> db.stats()
{
"db" : "test",
"collections" : 7, --collection 数量
"objects" : 28, --对象数量
"avgObjSize" : 50.57142857142857, --对象平均大小
"dataSize" : 1416, --数据大小
"storageSize" : 31744, --数据大小(含预分配空间)
"numExtents" : 7, --事件数量
"indexes" : 7, --索引数量
"indexSize" : 57344, --索引大小
"fileSize" : 50331648, --文件大小
"ok" : 1 --此番取stats 是不是健康
}
>
透过这么些工具,能够查看所在数据库的主导新闻
20.5 第三方工具
MongoDB 从一面世就取得广大开源爱好者和团体的推崇,在常用的监察框架如 cacti、
Nagios、Zabbix 等基础上进行扩大,进行MongoDB 的监督都是极度常有扶植的,有意思味的相爱的人
能够自已去多试试。

62 / 91
第五有个别 架构篇
第八十风姿罗曼蒂克章 Replica Sets复制集
MongoDB 援助在七个机械中通过异步复制达到故障转移和贯彻冗余。多机器中生机勃勃致时刻只
有大器晚成台是用以写操作。便是出于那个意况,为MongoDB 提供了多少生机勃勃致性的保险。担当
Primary 剧中人物的机器能把读操作分发给slave。
MongoDB 高可用可用分三种:
Master-Slave 主从复制跋山涉水的近义词
只必要在某三个劳动运维时加上–master 参数,而另一个服务丰硕–slave 与–source 参数,
就可以实现联机。MongoDB 的流行版本已不复推荐此方案。
Replica Sets复制集:
MongoDB 在 1.6 版本对开荒了新职能replica set,那比早先的replication 成效要强硬生机勃勃
些,扩张了故障自动切换和电动修复成员节点,各类DB 之间数据完全生龙活虎致,大大减少了维
护成功。auto shard 已经明朗表明不扶植replication paris,提出选取replica set,replica set
故障切换完全自动。
假如上图所示,Replica Sets 的构造非常形似叁个集群。是的,你完全能够把它正是集群,因
为它的确跟集群完毕的机能是平等的,个中多个节点假如出现故障,此外节点马上会将事情
接过来而无须停机操作。
21.1 部署Replica Sets
接下去将一步一步的给我们慌不择路一下实施步骤爬山涉水

63 / 91
1、 创立数据文件存款和储蓄路线
[root@localhost ~]# mkdir -p /data/data/r0
[root@localhost ~]# mkdir -p /data/data/r1
[root@localhost ~]# mkdir -p /data/data/r2
2、 成立日志文件路线
[root@localhost ~]# mkdir -p /data/log
3、创制主从key 文件,用于标记集群的私钥的风度翩翩体化路线,借使每种实例的key file 内容不生机勃勃
致,程序将不能够健康用。
[root@localhost ~]# mkdir -p /data/key
[root@localhost ~]# echo "this is rs1 super secret key" > /data/key/r0
[root@localhost ~]# echo "this is rs1 super secret key" > /data/key/r1
[root@localhost ~]# echo "this is rs1 super secret key" > /data/key/r2
[root@localhost ~]# chmod 600 /data/key/r*
4、启动3 个实例
[root@localhost ~]# /Apps/mongo/bin/mongod --replSet rs1 --keyFile /data/key/r0 --fork --port
28010 --dbpath /data/data/r0 --logpath=/data/log/r0.log --logappend
all output going to: /data/log/r0.log
forked process: 6573
[root@localhost ~]# /Apps/mongo/bin/mongod --replSet rs1 --keyFile /data/key/r1 --fork --port
28011 --dbpath /data/data/r1 --logpath=/data/log/r1.log --logappend
all output going to: /data/log/r1.log
forked process: 6580
[root@localhost ~]# /Apps/mongo/bin/mongod --replSet rs1 --keyFile /data/key/r2 --fork --port
28012 --dbpath /data/data/r2 --logpath=/data/log/r2.log --logappend
all output going to: /data/log/r2.log
forked process: 6585
[root@localhost ~]#
5、配置及开端化Replica Sets
[root@localhost bin]# /Apps/mongo/bin/mongo -port 28010
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:28010/test
> config_rs1 = {_id: 'rs1', members: [
... {_id: 0, host: 'localhost:28010', priority:1}, --成员IP 及端口,priority=1 指PRIMARY
... {_id: 1, host: 'localhost:28011'},
... {_id: 2, host: 'localhost:28012'}]
... }
{
"_id" : "rs1",
"members" : [
{

64 / 91
"_id" : 0,
"host" : "localhost:28010"
},
{
"_id" : 1,
"host" : "localhost:28011"
},
{
"_id" : 2,
"host" : "localhost:28012"
}
]
}
> rs.initiate(config_rs1); --开首化配置
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
6、查看复制集状态
> rs.status()
{
"set" : "rs1",
"date" : ISODate("2012-05-31T09:49:57Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "localhost:28010",
"health" : 1, --1 申明符合规律; 0 注解分外
"state" : 1, -- 1 表明是Primary; 2 表明是Secondary;
"stateStr" : "PKoleosIMAKugaY", --申明此机器是主库
"optime" : {
"t" : 1338457763000,
"i" : 1
},
"optimeDate" : ISODate("2012-05-31T09:49:23Z"),
"self" : true
},
{
"_id" : 1,
"name" : "localhost:28011",
"health" : 1,

65 / 91
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 23,
"optime" : {
"t" : 1338457763000,
"i" : 1
},
"optimeDate" : ISODate("2012-05-31T09:49:23Z"),
"lastHeartbeat" : ISODate("2012-05-31T09:49:56Z")
},
{
"_id" : 2,
"name" : "localhost:28012",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 23,
"optime" : {
"t" : 1338457763000,
"i" : 1
},
"optimeDate" : ISODate("2012-05-31T09:49:23Z"),
"lastHeartbeat" : ISODate("2012-05-31T09:49:56Z")
}
],
"ok" : 1
}
rs1:PRIMARY>
还能用isMaster 查看Replica Sets 状态。
rs1:PRIMARY> rs.isMaster()
{
"setName" : "rs1",
"ismaster" : true,
"secondary" : false,
"hosts" : [
"localhost:28010",
"localhost:28012",
"localhost:28011"
],
"maxBsonObjectSize" : 16777216,
"ok" : 1
}
rs1:PRIMARY>

66 / 91
21.2 主从操作日志oplog
MongoDB 的Replica Set 架构是由此八个日志来积攒写操作的,那几个日志就称为”oplog”。
oplog.rs 是三个恒定长度的 capped collection,它存在于”local”数据库中,用于记录 Replica
Sets 操作日志。在默许情形下,对于64 位的MongoDB,oplog 是非常的大的,能够达到规定的典型5%的磁
盘空间。oplog 的大大小小是足以由此mongod 的参数”—oplogSize”来改换oplog 的日记大小。
Oplog 内容样例:
rs1:PRIMARY> use local
switched to db local
rs1:PRIMARY> show collections
oplog.rs
system.replset
rs1:PRIMARY> db.oplog.rs.find()
{ "ts" : { "t" : 1338457763000, "i" : 1 }, "h" : NumberLong(0), "op" : "n", "ns" : "", "o" : { "msg" :
"initiating set" } }
{ "ts" : { "t" : 1338459114000, "i" : 1 }, "h" : NumberLong("5493127699725549585"), "op" : "i",
"ns" : "test.c1", "o" : { "_id" : ObjectId("4fc743e9aea289af709ac6b5"), "age" : 29, "name" :
"Tony" } }
rs1:PRIMARY>
字段表达:
ts: 某些操作的时日戳
op: 操作类型,如下爬山涉水
i: insert
d: delete
u: update
ns: 命名空间,也便是操作的collection name
o: document 的内容
翻开master 的oplog 元数据音信跋山涉水的近义词
rs1:PRIMARY> db.printReplicationInfo()
configured oplog size: 47.6837158203125MB
log length start to end: 1351secs (0.38hrs)
oplog first event time: Thu May 31 2012 17:49:23 GMT+0800 (CST)
oplog last event time: Thu May 31 2012 18:11:54 GMT+0800 (CST)
now: Thu May 31 2012 18:21:58 GMT+0800 (CST)
rs1:PRIMARY>
字段表达:
configured oplog size: 配置的oplog 文件大小
log length start to end: oplog 日志的启用时间段
oplog first event time: 第二个业务日志的发出时间
oplog last event time: 最终一个作业日志的发出时间

67 / 91
now: 今后的日子
查阅slave 的一块儿状态爬山涉水
rs1:PRIMARY> db.printSlaveReplicationInfo()
source: localhost:28011
syncedTo: Thu May 31 2012 18:11:54 GMT+0800 (CST)
= 884secs ago (0.25hrs)
source: localhost:28012
syncedTo: Thu May 31 2012 18:11:54 GMT+0800 (CST)
= 884secs ago (0.25hrs)
rs1:PRIMARY>
字段表明:
source: 从库的IP 及端口
syncedTo: 近年来的一块意况,延迟了多长时间等音讯
21.3 主从配置消息
在local 库中不独有有基本日志oplog 会集,还恐怕有三个凑合用于记录主从计划音信–
system.replset
rs1:PRIMARY> use local
switched to db local
rs1:PRIMARY> show collections
oplog.rs
system.replset
rs1:PRIMARY> db.system.replset.find()
{ "_id" : "rs1", "version" : 1, "members" : [
{
"_id" : 0,
"host" : "localhost:28010"
},
{
"_id" : 1,
"host" : "localhost:28011"
},
{
"_id" : 2,
"host" : "localhost:28012"
}
] }
rs1:PRIMARY>
从那些集结中能够见到,Replica Sets 的安插音信,也足以在别的叁个分子实例上实施rs.conf()
来查阅配置信息

68 / 91
21.4 管理维护Replica Sets
21.4.1 读写分离
有风流倜傥对第三方的工具,提供了一些得以让数据库实行读写分离的工具。大家今后是还是不是有贰个
疑点,从库借使能展开查询就更加好了,那样可以分地摊主人库的大气的查询央浼。
1、 先向主库中插入一条测量检验数据
[root@localhost bin]# ./mongo --port 28010
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:28010/test
rs1:PRIMARY> db.c1.insert({age:30})
db.c2rs1:PRIMARY> db.c1.find()
{ "_id" : ObjectId("4fc77f421137ea4fdb653b4a"), "age" : 30 }
2、 在从库进行查询等操作
[root@localhost bin]# ./mongo --port 28011
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:28011/test
rs1:SECONDARY> show collections
Thu May 31 22:27:17 uncaught exception: error: { "$err" : "not master and slaveok=false",
"code" : 13435 }
rs1:SECONDARY>
当查问时报错了,表达是个从库且无法奉行查询的操作
3、 让从库能够读,分担主库的下压力
rs1:SECONDARY> db.getMongo().setSlaveOk()
not master and slaveok=false
rs1:SECONDARY> show collections
c1
system.indexes
rs1:SECONDARY> db.c1.find()
{ "_id" : ObjectId("4fc77f421137ea4fdb653b4a"), "age" : 30 }
rs1:SECONDARY>
总的来说大家假若实施db.getMongo().setSlaveOk(), 大家就可查询从库了。
21.4.2 故障转移
复制集比古板的Master-Slave 有改革的地点正是她得以扩充故障的机关调换,假使大家停掉
复制凑集的三个分子,那么余下成员会再自动大选出多个成员,做为主库,例如:
咱俩将28010 那些主库停掉,然后再看一下复制集的意况

69 / 91
1、杀掉28010 端口的MongoDB
[root@localhost bin]# ps aux|grep mongod
root 6706 1.6 6.9 463304 6168 Sl 21:49 0:26
/Apps/mongo/bin/mongod --replSet rs1 --keyFile /data/key/r0 --fork --port 28010
root 6733 0.4 6.7 430528 6044 ? Sl 21:50 0:06
/Apps/mongo/bin/mongod --replSet rs1 --keyFile /data/key/r1 --fork --port 28011
root 6747 0.4 4.7 431548 4260 ? Sl 21:50 0:06
/Apps/mongo/bin/mongod --replSet rs1 --keyFile /data/key/r2 --fork --port 28012
root 7019 0.0 0.7 5064 684 pts/2 S+ 22:16 0:00 grep mongod
[root@localhost bin]# kill -9 6706
2、 查看复制集状态
[root@localhost bin]# ./mongo --port 28011
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:28011/test
rs1:SECONDARY> rs.status()
{
"set" : "rs1",
"date" : ISODate("2012-05-31T14:17:03Z"),
"myState" : 2,
"members" : [
{
"_id" : 0,
"name" : "localhost:28010",
"health" : 0,
"state" : 1,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"t" : 1338472279000,
"i" : 1
},
"optimeDate" : ISODate("2012-05-31T13:51:19Z"),
"lastHeartbeat" : ISODate("2012-05-31T14:16:42Z"),
"errmsg" : "socket exception"
},
{
"_id" : 1,
"name" : "localhost:28011",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"optime" : {

70 / 91
"t" : 1338472279000,
"i" : 1
},
"optimeDate" : ISODate("2012-05-31T13:51:19Z"),
"self" : true
},
{
"_id" : 2,
"name" : "localhost:28012",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1528,
"optime" : {
"t" : 1338472279000,
"i" : 1
},
"optimeDate" : ISODate("2012-05-31T13:51:19Z"),
"lastHeartbeat" : ISODate("2012-05-31T14:17:02Z")
}
],
"ok" : 1
}
rs1:SECONDARY>
能够看看28010 那个端口的MongoDB 出现了十二分,而系统活动公投了28012 这几个端口为主,
据此这么的故障管理机制,能将系统的风平浪静大大提升。
21.4.3 增减节点
MongoDB Replica Sets 不唯有提供高可用性的消除方案,它也还要提供负载均衡的缓慢解决方案,
增减Replica Sets 节点在其实使用中国和南美洲常广泛,比如当使用的读压力暴增时,3 台节点的环
境已不可能知足急需,那么就要求扩大部分节点将压力平均分配一下;当使用的压力时辰,可
以减小部分节点来压缩硬件财富的血本;同理可得那是三个悠远且反复的专门的职业。
21.4.3.1 扩大节点
官方给我们提了2 个方案用于增加节点,黄金时代种是经过oplog 来充实节点,风姿洒脱种是透过数据库
快照(--fastsync)和oplog 来充实节点,上边将各自介绍。
21.4.3.1.1 通过oplog 扩充节点
①、配置并运行新节点,启用28013那些端口给新的节点
[root@localhost ~]# mkdir -p /data/data/r3

71 / 91
[root@localhost ~]# echo "this is rs1 super secret key" > /data/key/r3
[root@localhost ~]# chmod 600 /data/key/r3
[root@localhost ~]# /Apps/mongo/bin/mongod --replSet rs1 --keyFile /data/key/r3 --fork --port
28013 --dbpath /data/data/r3 --logpath=/data/log/r3.log --logappend
all output going to: /data/log/r3.log
forked process: 10553
[root@localhost ~]#
②、增多此新节点到现存的Replica Sets
rs1:PRIMARY> rs.add("localhost:28013")
{ "ok" : 1 }
③、查看Replica Sets大家得以清楚的来看里边是何许增添28013那个新节点的.
手续后生可畏: 实行初阶化
rs1: PRIMARY > rs.status()
{
"set" : "rs1",
"date" : ISODate("2012-05-31T12:17:44Z"),
"myState" : 1,
"members" : [
……
{
"_id" : 3,
"name" : "localhost:28013",
"health" : 0,
"state" : 6,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"t" : 0,
"i" : 0
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2012-05-31T12:17:43Z"),
"errmsg" : "still initializing"
}
],
"ok" : 1
}
手续二: 实行多少同步
rs1:PRIMARY> rs.status()
{
"set" : "rs1",

72 / 91
"date" : ISODate("2012-05-31T12:18:07Z"),
"myState" : 1,
"members" : [
……
{
"_id" : 3,
"name" : "localhost:28013",
"health" : 1,
"state" : 3,
"stateStr" : "RECOVERING",
"uptime" : 16,
"optime" : {
"t" : 0,
"i" : 0
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2012-05-31T12:18:05Z"),
"errmsg" : "initial sync need a member to be primary or secondary
to do our initial sync"
}
],
"ok" : 1
}
步骤三: 初叶化同步到位
rs1:PRIMARY> rs.status()
{
"set" : "rs1",
"date" : ISODate("2012-05-31T12:18:08Z"),
"myState" : 1,
"members" : [
……
{
"_id" : 3,
"name" : "localhost:28013",
"health" : 1,
"state" : 3,
"stateStr" : "RECOVERING",
"uptime" : 17,
"optime" : {
"t" : 1338466661000,
"i" : 1
},
"optimeDate" : ISODate("2012-05-31T12:17:41Z"),

73 / 91
"lastHeartbeat" : ISODate("2012-05-31T12:18:07Z"),
"errmsg" : "initial sync done"
}
],
"ok" : 1
}
手续四: 节点增添达成,状态符合规律
rs1:PRIMARY> rs.status()
{
"set" : "rs1",
"date" : ISODate("2012-05-31T12:18:10Z"),
"myState" : 1,
"members" : [
……
{
"_id" : 3,
"name" : "localhost:28013",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 19,
"optime" : {
"t" : 1338466661000,
"i" : 1
},
"optimeDate" : ISODate("2012-05-31T12:17:41Z"),
"lastHeartbeat" : ISODate("2012-05-31T12:18:09Z")
}
],
"ok" : 1
}
④、验证数据现已一同过来了
[root@localhost data]# /Apps/mongo/bin/mongo -port 28013
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:28013/test
rs1:SECONDARY> rs.slaveOk()
rs1:SECONDARY> db.c1.find()
{ "_id" : ObjectId("4fc760d2383ede1dce14ef86"), "age" : 10 }
rs1:SECONDARY>
21.4.3.1.2 通过数据库快速照相(--fastsync)和oplog 增加节点
由此oplog 间接开展追加节点操作轻易且没有必要人工干预过多,但oplog 是capped collection,

74 / 91
运用循环的措施开展日志管理,所以利用oplog 的艺术张开充实节点,有望变成数据的不
同后生可畏,因为日志中存款和储蓄的音信有希望早已刷新过了。但是没什么,大家能够通过数据库快速照相
(--fastsync)和oplog 结合的艺术来增加节点,这种方式的操作流程是,先取某五个复制集成
员的概略文件来做为起先化数据,然后剩余的后生可畏对用oplog 日志来追,最后实现数据蒸蒸日上致性
①、取某叁个复制集成员的物理文件来做为开头化数据
[root@localhost ~]# scp -r /data/data/r3 /data/data/r4
[root@localhost ~]# echo "this is rs1 super secret key" > /data/key/r4
[root@localhost ~]# chmod 600 /data/key/r4
②、在取完物理文件后,在c1聚集插入一条新文书档案,用于最后验明正身此更新也一路了
rs1:PRIMARY> db.c1.find()
{ "_id" : ObjectId("4fc760d2383ede1dce14ef86"), "age" : 10 }
rs1:PRIMARY> db.c1.insert({age:20})
rs1:PRIMARY> db.c1.find()
{ "_id" : ObjectId("4fc760d2383ede1dce14ef86"), "age" : 10 }
{ "_id" : ObjectId("4fc7748f479e007bde6644ef"), "age" : 20 }
rs1:PRIMARY>
③、启用28014以此端口给新的节点
/Apps/mongo/bin/mongod --replSet rs1 --keyFile /data/key/r4 --fork --port 28014 --dbpath
/data/data/r4 --logpath=/data/log/r4.log --logappend --fastsync
④、添加28014节点
rs1:PRIMARY> rs.add("localhost:28014")
{ "ok" : 1 }
⑤、验证数据现已联手过来了
[root@localhost data]# /Apps/mongo/bin/mongo -port 28014
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:28014/test
rs1:SECONDARY> rs.slaveOk()
rs1:SECONDARY> db.c1.find()
{ "_id" : ObjectId("4fc760d2383ede1dce14ef86"), "age" : 10 }
{ "_id" : ObjectId("4fc7748f479e007bde6644ef"), "age" : 20 }
rs1:SECONDARY>
21.4.3.2 减弱节点
上面将刚刚加多的四个新节点28013 和28014 从复制聚焦去除掉,只需进行rs.remove 指令
就足以了,具体如下:
rs1:PRIMARY> rs.remove("localhost:28014")

75 / 91
{ "ok" : 1 }
rs1:PRIMARY> rs.remove("localhost:28013")
{ "ok" : 1 }
翻开复制集状态,能够观察今日独有28010、28011、28012 那多个成员,原来的28013 和
28014 都建功立业去除了
rs1:PRIMARY> rs.status()
{
"set" : "rs1",
"date" : ISODate("2012-05-31T14:08:29Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "localhost:28010",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"optime" : {
"t" : 1338473273000,
"i" : 1
},
"optimeDate" : ISODate("2012-05-31T14:07:53Z"),
"self" : true
},
{
"_id" : 1,
"name" : "localhost:28011",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 34,
"optime" : {
"t" : 1338473273000,
"i" : 1
},
"optimeDate" : ISODate("2012-05-31T14:07:53Z"),
"lastHeartbeat" : ISODate("2012-05-31T14:08:29Z")
},
{
"_id" : 2,
"name" : "localhost:28012",
"health" : 1,
"state" : 2,

76 / 91
"stateStr" : "SECONDARY",
"uptime" : 34,
"optime" : {
"t" : 1338473273000,
"i" : 1
},
"optimeDate" : ISODate("2012-05-31T14:07:53Z"),
"lastHeartbeat" : ISODate("2012-05-31T14:08:29Z")
}
],
"ok" : 1
}
rs1:PRIMARY>
第六十一章 Sharding分片
那是风流倜傥种将海量的多少水平扩充的数据库集群系统,数据分表存款和储蓄在sharding 的各种节点
上,使用者通过简单的布署就可以很便利地创设一个分布式MongoDB 集群。
MongoDB 的数据分块称为 chunk。各种 chunk 都以 Collection 中风姿浪漫段连接的数量记录,通
常最大尺寸是 200MB,超过则生成新的数据块。
要创设贰个 MongoDB Sharding Cluster,要求三种剧中人物跋山涉水的近义词
Shard Server
即存款和储蓄实际数据的分片,各类Shard 能够是八个mongod 实例,也得以是大器晚成组mongod 实例
组合的Replica Set。为了落到实处每一个Shard 内部的auto-failover,MongoDB 官方建议每一种Shard
为一组Replica Set。
Config Server
为了将八个一定的collection 存款和储蓄在多少个shard 中,供给为该collection 钦赐八个shard key,
比方{age: 1} ,shard key 能够操纵该条记录属于哪个chunk。Config Servers 正是用来积累爬山涉水
有着shard 节点的铺排新闻、每一个chunk 的shard key 范围、chunk 在各shard 的布满境况、
该集群中存有DB 和collection 的sharding 配置音信。
Route Process
这是贰个前端路由,顾客端因而接入,然后询问Config Servers 须要到哪些Shard 上询问或
保存记录,再连接相应的Shard 实行操作,最终将结果再次回到给顾客端。顾客端只须求将原先
发给mongod 的查询或更新央求稳如泰山地发给Routing Process,而不必关注所操作的记录
仓储在哪个Shard 上。
下边大家在相符台物理机械上营造多个简练的 Sharding Cluster跋山涉水的近义词
架构图如下爬山涉水

77 / 91
Shard Server 1:20000
Shard Server 2:20001
Config Server :30000
Route Process:40000
22.1 启动Shard Server
mkdir -p /data/shard/s0 --创立数量目录
mkdir -p /data/shard/s1
mkdir -p /data/shard/log --创立日志目录
/Apps/mongo/bin/mongod --shardsvr --port 20000 --dbpath /data/shard/s0 --fork --logpath
/data/shard/log/s0.log --directoryperdb --启动Shard Server 实例1
/Apps/mongo/bin/mongod --shardsvr --port 20001 --dbpath /data/shard/s1 --fork --logpath
/data/shard/log/s1.log --directoryperdb --启动Shard Server 实例2
22.2 启动Config Server
mkdir -p /data/shard/config --创立数量目录
/Apps/mongo/bin/mongod --configsvr --port 30000 --dbpath /data/shard/config --fork --logpath
/data/shard/log/config.log --directoryperdb --启动Config Server 实例
22.3 启动Route Process
/Apps/mongo/bin/mongos --port 40000 --configdb localhost:30000 --fork --logpath
/data/shard/log/route.log --chunkSize 1 --启动Route Server 实例

78 / 91
mongos 运转参数中,chunkSize 这热气腾腾项是用来钦定chunk 的深浅的,单位是MB,暗中认可大小
为200MB,为了便于测量试验Sharding 效果,我们把chunkSize 钦定为 1MB。
22.4 配置Sharding
接下去,大家运用MongoDB Shell 登入到mongos,增添Shard 节点
[root@localhost ~]# /Apps/mongo/bin/mongo admin --port 40000 --此操作须求连接admin 库
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:40000/admin
> db.runCommand({ addshard:"localhost:20000" }) --添加 Shard Server
{ "shardAdded" : "shard0000", "ok" : 1 }
> db.runCommand({ addshard:"localhost:20001" })
{ "shardAdded" : "shard0001", "ok" : 1 }
> db.runCommand({ enablesharding:"test" }) --设置分片存款和储蓄的数据库
{ "ok" : 1 }
> db.runCommand({ shardcollection: "test.users", key: { _id:1 }}) --设置分片的聚集名称,且必
须钦定Shard Key,系统会自行成立索引
{ "collectionsharded" : "test.users", "ok" : 1 }
>
22.5 验证Sharding寻常办事
我们已经对test.users 表进行了分片的设置,上边我们们插入一些数量看一下结果
> use test
switched to db test
> for (var i = 1; i <= 500000; i++) db.users.insert({age:i, name:"wangwenlong", addr:"Beijing",
country:"China"})
> db.users.stats()
{
"sharded" : true, --表达此表已被shard
"ns" : "test.users",
"count" : 500000,
"size" : 48000000,
"avgObjSize" : 96,
"storageSize" : 66655232,
"nindexes" : 1,
"nchunks" : 43,
"shards" : {
"shard0000" : { --在这里分片实例上约有24.5M 数据
"ns" : "test.users",
"count" : 254889,
"size" : 24469344,
"avgObjSize" : 96,

79 / 91
"storageSize" : 33327616,
"numExtents" : 8,
"nindexes" : 1,
"lastExtentSize" : 12079360,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 11468800,
"indexSizes" : {
"_id_" : 11468800
},
"ok" : 1
},
"shard0001" : { --在那分片实例上约有23.5M 数据
"ns" : "test.users",
"count" : 245111,
"size" : 23530656,
"avgObjSize" : 96,
"storageSize" : 33327616,
"numExtents" : 8,
"nindexes" : 1,
"lastExtentSize" : 12079360,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 10649600,
"indexSizes" : {
"_id_" : 10649600
},
"ok" : 1
}
},
"ok" : 1
}
>
咱俩看一下磁盘上的物理文件景况
[root@localhost bin]# ll /data/shard/s0/test --此分片实例上有数据产生
总计 262420
-rw------- 1 root root 16777216 06-03 15:21 test.0
-rw------- 1 root root 33554432 06-03 15:21 test.1
-rw------- 1 root root 67108864 06-03 15:22 test.2
-rw------- 1 root root 134217728 06-03 15:24 test.3
-rw------- 1 root root 16777216 06-03 15:21 test.ns
[root@localhost bin]# ll /data/shard/s1/test --此分片实例上有数据产生
总计 262420

80 / 91
-rw------- 1 root root 16777216 06-03 15:21 test.0
-rw------- 1 root root 33554432 06-03 15:21 test.1
-rw------- 1 root root 67108864 06-03 15:22 test.2
-rw------- 1 root root 134217728 06-03 15:23 test.3
-rw------- 1 root root 16777216 06-03 15:21 test.ns
[root@localhost bin]#
看上述结果,表明test.users 会集已经被中庸之道管理了,可是透过mongos 路由,我们并认为
不到是数量贮存在哪些shard 的chunk 上的,那就是MongoDB 顾客体验上的贰个优势,即
对客商是晶莹的。
22.6 管理保养Sharding
22.6.1 列出具备的Shard Server
> db.runCommand({ listshards: 1 }) --列出具有的Shard Server
{
"shards" : [
{
"_id" : "shard0000",
"host" : "localhost:20000"
},
{
"_id" : "shard0001",
"host" : "localhost:20001"
}
],
"ok" : 1
}
22.6.2 查看Sharding信息
> printShardingStatus() --查看Sharding 信息
--- Sharding Status ---
sharding version: { "_id" : 1, "version" : 3 }
shards:
{ "_id" : "shard0000", "host" : "localhost:20000" }
{ "_id" : "shard0001", "host" : "localhost:20001" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "test", "partitioned" : true, "primary" : "shard0000" }
test.users chunks:

81 / 91
shard0000 1
{ "_id" : { $minKey : 1 } } -->> { "_id" : { $maxKey : 1 } } on :
shard0000 { "t" : 1000, "i" : 0 }
>
22.6.3 判别是还是不是是Sharding
> db.runCommand({ isdbgrid:1 })
{ "isdbgrid" : 1, "hostname" : "localhost", "ok" : 1 }
>
22.6.4 对现存的表张开Sharding
刚才我们是对表test.users 举行分片了,下边大家将对库中幸存的未分片的表test.users_2 进
行分片处理
表最早状态如下,能够看见他不曾被一分为二过爬山涉水
> db.users_2.stats()
{
"ns" : "test.users_2",
"sharded" : false,
"primary" : "shard0000",
"ns" : "test.users_2",
"count" : 500000,
"size" : 48000016,
"avgObjSize" : 96.000032,
"storageSize" : 61875968,
"numExtents" : 11,
"nindexes" : 1,
"lastExtentSize" : 15001856,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 20807680,
"indexSizes" : {
"_id_" : 20807680
},
"ok" : 1
}
对其进展分片管理:
> use admin

82 / 91
switched to db admin
> db.runCommand({ shardcollection: "test.users_2", key: { _id:1 }})
{ "collectionsharded" : "test.users_2", "ok" : 1 }
双重查看分片后的表的意况,能够观察它早已被大家分片了
> use test
switched to db test
> db.users_2.stats()
{
"sharded" : true,
"ns" : "test.users_2",
"count" : 505462,
……
"shards" : {
"shard0000" : {
"ns" : "test.users_2",
……
"ok" : 1
},
"shard0001" : {
"ns" : "test.users_2",
……
"ok" : 1
}
},
"ok" : 1
}
>
22.6.5 新增Shard Server
刚才大家演示的是新添分片表,接下去大家演示怎样新扩充Shard Server
启航贰个新Shard Server 进度
[root@localhost ~]# mkdir /data/shard/s2
[root@localhost ~]# /Apps/mongo/bin/mongod --shardsvr --port 20002 --dbpath /data/shard/s2
--fork --logpath /data/shard/log/s2.log --directoryperdb
all output going to: /data/shard/log/s2.log
forked process: 6772
配置新Shard Server
[root@localhost ~]# /Apps/mongo/bin/mongo admin --port 40000
MongoDB shell version: 1.8.1

83 / 91
connecting to: 127.0.0.1:40000/admin
> db.runCommand({ addshard:"localhost:20002" })
{ "shardAdded" : "shard0002", "ok" : 1 }
> printShardingStatus()
--- Sharding Status ---
sharding version: { "_id" : 1, "version" : 3 }
shards:
{ "_id" : "shard0000", "host" : "localhost:20000" }
{ "_id" : "shard0001", "host" : "localhost:20001" }
{ "_id" : "shard0002", "host" : "localhost:20002" } --新增Shard Server
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "test", "partitioned" : true, "primary" : "shard0000" }
test.users chunks:
shard0002 2
shard0000 21
shard0001 21
too many chunksn to print, use verbose if you want to force print
test.users_2 chunks:
shard0001 46
shard0002 1
shard0000 45
too many chunksn to print, use verbose if you want to force print
翻看分片表状态,以表达新Shard Server
> use test
switched to db test
> db.users_2.stats()
{
"sharded" : true,
"ns" : "test.users_2",
……
"shard0002" : { --新的Shard Server 本来就有数量
"ns" : "test.users_2",
"count" : 21848,
"size" : 2097408,
"avgObjSize" : 96,
"storageSize" : 2793472,
"numExtents" : 5,
"nindexes" : 1,
"lastExtentSize" : 2097152,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 1277952,

84 / 91
"indexSizes" : {
"_id_" : 1277952
},
"ok" : 1
}
},
"ok" : 1
}
>
大家得以窥见,当我们新添Shard Server 后数据自动布满到了新Shard 上,那是由MongoDB
当中自已兑现的。
22.6.6 移除Shard Server
微微时候有于硬件财富有限,所以大家必须要实行部分回笼工作,上边大家就要将刚刚启用
的Shard Server 回笼,系统率先会将要这里个将在被移除的Shard Server 上的数码先平均分配
到其余的Shard Server 上,然后最后在将以此Shard Server 踢下线, 大家要求不停的调用
db.runCommand({"removeshard" : "localhost:二〇〇一2"});来考察那么些移除操作实行到何地了爬山涉水
> use admin
switched to db admin
> db.runCommand({"removeshard" : "localhost:20002"});
{
"msg" : "draining started successfully",
"state" : "started",
"shard" : "shard0002",
"ok" : 1
}
> db.runCommand({"removeshard" : "localhost:20002"});
{
"msg" : "draining ongoing",
"state" : "ongoing",
"remaining" : {
"chunks" : NumberLong(44),
"dbs" : NumberLong(0)
},
"ok" : 1
}
……
> db.runCommand({"removeshard" : "localhost:20002"});
{
"msg" : "draining ongoing",
"state" : "ongoing",
"remaining" : {

85 / 91
"chunks" : NumberLong(1),
"dbs" : NumberLong(0)
},
"ok" : 1
}
> db.runCommand({"removeshard" : "localhost:20002"});
{
"msg" : "removeshard completed successfully",
"state" : "completed",
"shard" : "shard0002",
"ok" : 1
}
> db.runCommand({"removeshard" : "localhost:20002"});
{
"assertion" : "can't find shard for: localhost:20002",
"assertionCode" : 13129,
"errmsg" : "db assertion failure",
"ok" : 0
}
最终移除后,当我们再一次调用db.runCommand({"removeshard" : "localhost:二〇〇三2"});的时候系统
会报错,已便通告大家不真实二零零三2 这么些端口的Shard Server 了,因为它曾经被移除掉了。
接下去我们看一下表中的数据布满跋山涉水的近义词
> use test
switched to db test
> db.users_2.stats()
{
"sharded" : true,
"ns" : "test.users_2",
"count" : 500000,
"size" : 48000000,
"avgObjSize" : 96,
"storageSize" : 95203584,
"nindexes" : 1,
"nchunks" : 92,
"shards" : {
"shard0000" : {
"ns" : "test.users_2",
"count" : 248749,
"size" : 23879904,
"avgObjSize" : 96,
"storageSize" : 61875968,
"numExtents" : 11,
"nindexes" : 1,

86 / 91
"lastExtentSize" : 15001856,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 13033472,
"indexSizes" : {
"_id_" : 13033472
},
"ok" : 1
},
"shard0001" : {
"ns" : "test.users_2",
"count" : 251251,
"size" : 24120096,
"avgObjSize" : 96,
"storageSize" : 33327616,
"numExtents" : 8,
"nindexes" : 1,
"lastExtentSize" : 12079360,
"paddingFactor" : 1,
"flags" : 1,
"totalIndexSize" : 10469376,
"indexSizes" : {
"_id_" : 10469376
},
"ok" : 1
}
},
"ok" : 1
}
能够观察数据又被平均分配到了另外2 台Shard Server 上了,对业务没什么超大的影响。
第七十五章 Replica Sets + Sharding
MongoDB Auto-Sharding 化解了海量存款和储蓄和动态扩大体积的主题材料,但离实际生育情形所需的高可
靠、高可用还有些间隔,所以有了” Replica Sets + Sharding”的减轻方案:
Shard:
应用 Replica Sets,确认保证每种数据节点都具备备份、自动容错转移、自动还原本领。
Config:
行使3 个布局服务器,确认保证元数据完整性
Route:
使用3 个路由进程,完毕负载平衡,进步顾客端接入品质
以下我们配备一个 Replica Sets + Sharding 的条件,架构图如下:

87 / 91
盛放的端口如下跋山涉水的近义词
长机 IP 服务及端口
Server A 192.168.3.231 mongod shard1_1:27017
mongod shard2_1:27018
mongod config1:20000
mongs1:30000
Server B 192.168.3.232 mongod shard1_2:27017
mongod shard2_2:27018
mongod config2:20000
mongs2:30000
Server C 192.168.3.233 mongod shard1_3:27017
mongod shard2_3:27018
mongod config3:20000
mongs3:30000
23.1 创建数量目录
在Server A 上:
[root@localhost bin]# mkdir -p /data/shard1_1
[root@localhost bin]# mkdir -p /data/shard2_1

88 / 91
[root@localhost bin]# mkdir -p /data/config
在Server B 上:
[root@localhost bin]# mkdir -p /data/shard1_2
[root@localhost bin]# mkdir -p /data/shard2_2
[root@localhost bin]# mkdir -p /data/config
在Server C 上:
[root@localhost bin]# mkdir -p /data/shard1_3
[root@localhost bin]# mkdir -p /data/shard2_3
[root@localhost bin]# mkdir -p /data/config
23.2 配置Replica Sets
23.2.1 配置shard1所用到的Replica Sets
在Server A 上:
[root@localhost bin]# /Apps/mongo/bin/mongod --shardsvr --replSet shard1 --port 27017
--dbpath /data/shard1_1 --logpath /data/shard1_1/shard1_1.log --logappend --fork
[root@localhost bin]# all output going to: /data/shard1_1/shard1_1.log
forked process: 18923
在Server B 上:
[root@localhost bin]# /Apps/mongo/bin/mongod --shardsvr --replSet shard1 --port 27017
--dbpath /data/shard1_2 --logpath /data/shard1_2/shard1_2.log --logappend --fork
forked process: 18859
[root@localhost bin]# all output going to: /data/shard1_2/shard1_2.log
[root@localhost bin]#
在Server C 上:
[root@localhost bin]# /Apps/mongo/bin/mongod --shardsvr --replSet shard1 --port 27017
--dbpath /data/shard1_3 --logpath /data/shard1_3/shard1_3.log --logappend --fork
all output going to: /data/shard1_3/shard1_3.log
forked process: 18768
[root@localhost bin]#
用mongo 连接在这之中一台机械的27017 端口的mongod,起始化Replica Sets“shard1”,试行:
[root@localhost bin]# ./mongo --port 27017
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:27017/test
> config = {_id: 'shard1', members: [

89 / 91
... {_id: 0, host: '192.168.3.231:27017'},
... {_id: 1, host: '192.168.3.232:27017'},
... {_id: 2, host: '192.168.3.233:27017'}]
... }
……
> rs.initiate(config)
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
23.2.2 配置shard2所用到的Replica Sets
在Server A 上:
[root@localhost bin]# /Apps/mongo/bin/mongod --shardsvr --replSet shard2 --port 27018
--dbpath /data/shard2_1 --logpath /data/shard2_1/shard2_1.log --logappend --fork
all output going to: /data/shard2_1/shard2_1.log
[root@localhost bin]# forked process: 18993
[root@localhost bin]#
在Server B 上:
[root@localhost bin]# /Apps/mongo/bin/mongod --shardsvr --replSet shard2 --port 27018
--dbpath /data/shard2_2 --logpath /data/shard2_2/shard2_2.log --logappend --fork
all output going to: /data/shard2_2/shard2_2.log
forked process: 18923
[root@localhost bin]#
在Server C 上:
[root@localhost bin]# /Apps/mongo/bin/mongod --shardsvr --replSet shard2 --port 27018
--dbpath /data/shard2_3 --logpath /data/shard2_3/shard2_3.log --logappend --fork
[root@localhost bin]# all output going to: /data/shard2_3/shard2_3.log
forked process: 18824
[root@localhost bin]#
用mongo 连接在那之中风度翩翩台机器的27018 端口的mongod,初叶化Replica Sets “shard2”,执行:
[root@localhost bin]# ./mongo --port 27018
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:27018/test
> config = {_id: 'shard2', members: [
... {_id: 0, host: '192.168.3.231:27018'},

90 / 91
... {_id: 1, host: '192.168.3.232:27018'},
... {_id: 2, host: '192.168.3.233:27018'}]
... }
……
> rs.initiate(config)
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
23.3 配置3 台Config Server
在Server A、B、C上执行:
/Apps/mongo/bin/mongod --configsvr --dbpath /data/config --port 20000 --logpath
/data/config/config.log --logappend --fork
23.4 配置3 台Route Process
在Server A、B、C上执行:
/Apps/mongo/bin/mongos --configdb
192.168.3.231:20000,192.168.3.232:20000,192.168.3.233:20000 --port 30000 --chunkSize 1
--logpath /data/mongos.log --logappend --fork
23.5 配置Shard Cluster
连天到当中意气风发台机械的端口30000 的mongos 进程,并切换成admin 数据库做以下配置
[root@localhost bin]# ./mongo --port 30000
MongoDB shell version: 1.8.1
connecting to: 127.0.0.1:30000/test
> use admin
switched to db admin
>db.runCommand({addshard:"shard1/192.168.3.231:27017,192.168.3.232:27017,192.168.3.233:
27017"});
{ "shardAdded" : "shard1", "ok" : 1 }
>db.runCommand({addshard:"shard2/192.168.3.231:27018,192.168.3.232:27018,192.168.3.233:
27018"});
{ "shardAdded" : "shard2", "ok" : 1 }
>
激活数据库及集结的分片
db.runCommand({ enablesharding:"test" })
db.runCommand({ shardcollection: "test.users", key: { _id:1 }})

91 / 91
23.6 验证Sharding不奇怪干活
连天到里头生机勃勃台机器的端口30000 的mongos 进度,并切换来test 数据库,以便增加测量试验数

use test
for(var i=1;i<=200000;i++) db.users.insert({id:i,addr_1:"Beijing",addr_2:"Shanghai"});
db.users.stats()
{
"sharded" : true,
"ns" : "test.users",
"count" : 200000,
"size" : 25600384,
"avgObjSize" : 128,
"storageSize" : 44509696,
"nindexes" : 2,
"nchunks" : 15,
"shards" : {
"shard0000" : {
……
},
"shard0001" : {
……
}
},
"ok" : 1
}
能够见到Sharding搭建形成功了,跟大家期待的结果日新月异致,至此我们就将Replica Sets与Sharding
结合的架构也学习实现了。

本文由新金沙国际手机版发布于www.6165.com,转载请注明出处:mongoDB配制及学习

关键词:

www.6165.comWinCE系统资源查看器

     今天偶然发现了一个WinCE下的系统资源查看工具,个人觉得非常不错,值得收藏。 www.6165.comWinCE系统资源查看...

详细>>

www.6165.com月薪3万的新媒体人都在用这些运营工具

图片来源:36Kr 工具很多,可以先浏览一下收藏起来,等到用的时候就想起来了。 微信公众号运营辅助工具汇总(持...

详细>>

几款常用App安装量渠道统计(移动广告监控)工

几款常用App安装量渠道统计(移动广告监控)工具。目前渠道投放的现状大多是点击很多,安装很少,留存更是骨感...

详细>>

Java学习心得之 Linux下搭建Java环境

二、 JDK安装 1.从sun主页(Java学习心得之 Linux下搭建Java环境。for Linux版本,例如jdk-8u91-linux-x64.tar.gz 2.解压JDK文件sud...

详细>>