目录:
1. 前言······························Click Me
2. MongoDBs特性························ Click Me
3. MongoDB结构 ························ Click Me
4. MongoDB安装························· Click Me
5. MongoDB的部署························ Click Me
此文档只涉及MongoDB基本的部署操作,不限于数据操作等.如有需求请参阅MongoDB小组的PPT 等相关资料谢谢!编者能力有限 如有疑问或者错误点请联系我。
文档中可能存在 双引号 或者 关键字大小空格等问题,word自动转换的问题请注意!!!
MongoDB是一个基于分布式文件存储的数据库,是一个可扩展、高性能的下一代数据库(文档存储),由C++语言编写FF0C旨在为web应用提供可扩展的高性能数据存储解决方案。它的特点是高性能、易部署、易使用,存储数据非常方便,主要特性有:
1模式自由,支持动态查询、完全索引,可轻易查询文档中内嵌的对象及数组。作为文档型数据库,mongodb基本具有关系型数据库的除了join及数据库事物外的其它特点。
2面向集合存储,易存储对象类型的数据, 包括文档内嵌对象及数组 。
3高效的数据存储,支持二进制数据及大型对象(如照片和视频)。
4支持复制和故障恢复;提供了主-从、复制集模式的数据复制及服务器之间的数据复制。
5自动分片以支持云级别的伸缩性,支持水平的数据库集群,可动态添加额外的服务器
传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB同样也是由数据库(database) 、集合(collection,又称为数据集)、文档对象(document)三个层次组成。 MongoDB里的集合对应于关系型数据库里的表,但是集合中没有列、行和关系的概念,这体现了模式自由的特点。
数据文件与内存使用
在MongoDB的数据文件夹中(默认路径是/data/db)为构成数据库的所有文件。为提高效率使用内存映射文件进行管理(含数据和索引),但是占用内存大小无法指定,所以,如果数据量很大的情况下,内存会占用很多。
在添加文档时,先写入到内存,而后再同步到数据文件。同步的速度很快。在1.6以后的版本(不含1.6)中,mongodb服务会记录一个更新文档的操作日志,一旦服务突然宕机,下次再次重启时,会从日志中将宕机前还在内存中没有保存的数据写入到磁盘中。
每一个数据库都包含一个.ns文件和一些数据文件,其中数据文件会随着数据量的增加而变多。
数据空间采用预分配,目的是为了避免形成过多的硬盘碎片。它为每个数据库分配一系列文件,每个数据文件都会被预分配一个大小,第一个文件名字为“.0 ”,大小为64MB,当预分配空间不够时,将会自动分配下一个数据文件。第二个文件“.1”为128MB ,第三个文件“.2”为256MB,数据文件每新增一次,大小都会是上一个数据文件的2倍,名称的后缀,会在上一个数据文件的后缀数字上加1。在32位模式运行时支持的最大文件为2GB。随着数据量的增加,可以在其数据目录里看到这些不断递增的文件。
在64位系统中,不限制总文件大小。不过,当单一数据文件到达2GB后,以后再预分配的文件,都是2GB,不会再以2倍来递增。
如,有一个数据库名字叫做content,那么构成content这个数据库的文件就会由content.ns,content.0,content.1,content.2等等组成。在开始启动服务时,content数据库不会存在,当进行了第一次更新操作时,会自动创建该content数据库,预分配空间,产生初始的两个文件content.ns,content.0 (64位机器的数据文件,初始预分配可能到content.1)。随后,随着数据的增加,64MB的content.0空间不够时,会分配新的数据文件content.1。依此类推。
MongoDB预分配方式保证写入性能的稳定(这种方式在服务启动时可以使用--noprealloc关闭)。预分配在后台进行,每个预分配的文件都用0进行填充。这会让MongoDB始终保持额外的空间和空余的数据文件,从而避免了数据增长过快而带来的分配磁盘空间引起的阻塞。
预分配文件,并不是在前一个数据文件写完后再分配的,而是在其写完前就已经开始分配,所以,在一般的应用中,预分配时,对添加的堵塞不大。除非像测试一样,瞬间出现百万级左右的数据添加请求,才会对添加带来较大影响。
MongoDB没有自动递增或序列特性,当BSON对象插入到数据库中时,如果没有提供“_id”字段 ,数据库会自动生成一个ObjectId对象作为“_id”的值插入到集合中作为该文档的主键(这就避免了其它数据库意外地选择相同的惟一标识符的情况) ,“_id”的值由4字节的时间戳,3字节的机器号,2字节的进程id以及3字节的自增计数组成。当然字段“_id”的值可以手动生成(任意类型都可),只要能够保证惟一性。
1.下载
连接到:http://www.mongodb.org/downloads 根据系统版本进行下载
目前已针对 Windows,Liunx,Mac OS X ,Solaris出了相应版本,
请注意:简单测试或者开发环境可以考虑32bit否则请选择64bit 具体原因上述已经说的很清楚了在此就不做说明。
2.MongoDB启动(XP和Liunx 适用)
1. 运行cmd进入DB 的bin目录 :
mongod.exe --dbpath=E:\mongodb\data--logpath=E:\mongodb\logs\logs.txt --logappend --bind_ip127.0.0.1--directoryperdb
这样服务器就启动成功了,然后重新打开一个CMD.进入db 的bin 目录下,输入
mongo 就可以看到以下画面,你就可以进行操作了。
注意:如果你在启动服务中加了—auth,进入mongo下面后你将不能直接使用基本的语法,原因很简单…你没权限~ 新的库你需要use admin 下然后 db.addUser(“zhangsan”,”zhangsan”) 创建用户和密码可以自己定义.
3.启动的常用参数
Mongod 启动服务时,常用参数
--dbpath arg (=/data/db/) 指定数据存放目录
--logpath arg 指定日志存放目录
--logappend 指定日志是以追加还是以覆盖的方式写入日志文件
--port 指定端口号,默认27017
--maxConns arg 最大连接数,默认是10
--bing_ip 绑定IP
--directoryperdb 为每个DB创建一个独立子目录
--quiet 静默模式,生成最少的日志信息
--fork 以创建子进程的方式运行
--cpu 周期性的显示cpu和io的使用情况
--noauth 无认证模式运行
--auth 认证模式运行
--quota 开始数据库配额管理
--quotaFiles arg 规定每个数据库允许的文件数
--nssize arg 数据库.ns文件的默认大小,现在是16MB。
--sysinfo 打印系统诊断信息
启用复制配置参数:
--master mastermode 主复制模式
--slave slavemode 从复制模式
--sourcearg <server:port>当为从时,指定主的地址和端口
--only arg 当为从时,指定需要从主节点复制的单一库,默认是所有都复制
--autoresync 自动的重新执行完整的同步
--oplogSizearg 指明mongod的oplog collection大小,单位为MB,mongodb的每次 操作都会先写入oplog,再实际操作,且在replica set模式中,该日 志用于各个服务器间的同步,网速较慢时应该适当放大。
--opIdMemarg 指定存储操作日志的内存大小
--slavedelayarg 间隔多长时间slave进行同步
--replSet 配置成Replica Sets模式
分片参数配置:
--configsvr 指定shard中的配置服务器
--shardsvr 指定shard服务器
--configdb 指定config server
--config 用配置文件作为启动参数(window和liunx下适用)
配置文件参考:
4.Mongod加入服务
1.加入XP服务:
运行cmd进入DB 的bin目录
start mongod.exe--dbpath=E:\mongodb\data --logpath=E:\mongodb\logs\logs.txt --logappend--bind_ip 127.0.0.1–serviceName montest --directoryperdb –install
以上 data 和logs 文件建议提前建好 路径可以自己更改,上述的路径是在我的mongodb下面建立的2个文件夹
这样就显示添加服务成功!!!!去服务中查看把。
说明:建好服务后我们看见服务名字是 mongotest 显示名字是 Mongo db,用window键+R我们可以直接 net start mongotest 进行启动,请注意区别服务器名字和显示名字的区别! 注意:因为建立好服务默认是自启动的如果没有需要建议改为手动。
Windows服务控制管理器选项:
(可以在cmd到db下输入 mongod /?查阅相关帮助文档)
--install 安装安装Windows服务
--remove 删除删除Windows服务
--reinstall重新安装Windows服务(相当于删除在安装这个服务)
--serviceName arg Windows服务名称
--serviceDisplayName arg Windows服务的显示名称
--serviceDescription arg Windows服务介绍
--serviceUser arg 服务执行系统帐户 (一般不用,除非你有特殊需要)
--servicePassword arg服务执行系统帐户密码 (一般不用,除非你有特殊需要)
注意:如果发生 mongodb服务无法运行的:原因是data 目录 lock 数据的问题,将mongod.lock文件删掉就没问题了
2.加入Liunx服务:
1.加入liunx的就比较简单了你可以直接按照XP 的方法在 /etc/rc.local文件中加入单独启动服务的参数语句
如:mongod.exe --dbpath=用户目录\data --logpath=用户目录\mongodb\logs\logs.txt--logappend --bind_ip 127.0.0.1--directoryperdb
我这里是以--config 的方式启动的,都大同小异,唯一要说的是如果你要方便修改启动的参数可以考虑配置文件,因为它更直观…(其实我也挺不喜欢启动的时候带一大堆的启动参数~看着比较凌乱 比较喜欢简单的东西,比如….xxxxxx)。
咳咳跑题了。。。不是你加了那么一句话就好了 然后直接在bin目录下 ./mongo 就完事了!!! 你需要reboot!! 这样它才会自己启动的!
MongoDB的数据复制
Mongodb支持数据复制功能。
复制主要分为主从复制(master\slave)方式和复制集(eplica Sets)方式配置。复制集(eplica Sets)是在1.6版本以后,才开始使用,也是现在mongodb官方建议使用的方式。除这两种方式外的其它方式,如主主复制(master\master)、互为主从复制(Replica Pairs)等 在1.6版本后,都不再建议使用。
1) 主从复制模式(master\slave)
A 说明
主从复制是MongoDB支持的最常见的复制方式。这种方式是非常灵活的,可用于备份、故障转移、分散读请求等。主数据库更新数据后,会自动把数据复制到从数据库中。
主从复制中,所有的从节点数据,必须要从一个主节点进行复制。所有的从节点所含的数据源(自有数据源local除外)中,不能主动写入数据。
在集群中,从节点的数量没有限制,但是,过多的从节点会使主节点超负荷。
主节点负责写和读,从节点只负责读。而要实现主、从节点分别做读、写分离,则是在各个Driver层设置slaveOk的值来实现的。
B 配置
基本的配置步骤是启动一个主结点和一个或多个从结点,每一个从结点知道主结点的地址。
主从数据库可是一主一从(或多从)(多个节点未必是多台独立的服务器,可在一台服务器上配置多个mongodb节点,使用--dbpath参数指定不同的数据库目录)。
配置一个主数据库节点:
$bin/mongod --master [--dbpath /data/masterdb/]
配置一个从数据库节点:
$bin/mongod --slave --source <masterhostname>[:<port>] [--dbpath/data/slavedb/]
dbpath指定的数据库目录,必须是已经存在的。
可以设置--slavedelay参数,如: --slavedelay 10 表示10秒同步一次数据。
当主数据库节点与从数据库节点启动成功后,会在dbpath指定的数据库目录中,先产生一个名为local的数据源。这个数据源,对于各个数据库节点来说,都是局部自有的,内容不会被复制。如果需要保存 不需复制的数据,可以保存到该数据源中。该数据源主要记录集群的主从节点信息以及更新日志信息等。
可以通过
$bin/mongod<masterhostname>:[port]/local
登录到master主数据库节点的local数据库中。
在这个库中,有oplog.$main集合,用来记录从服务器需要的操作队列信息。还有slaves集合,包含各个从服务器的信息。
oplog集合是为了保证从结点能够跟主结点同步。只存储会改变数据库状态的操作。查询,不会存在oplog中。
oplog是相当于一个简单的循环缓冲。当新的操作存入oplog时,它们会自动地覆盖掉最老的操作。这保证了oplog的大小不会超过一个界限值。这个界限值在启动主结点时,使用--oplogSize选项指定。oplog的大小(单位是MB)。默认情况下,主结点将为oplog使用5%的磁盘空闲空间(64位机器最小值为1G,32位机器为50M)。这个空间将分配给local数据库并且在服务器启动时进行预分配。
可以通过
$bin/mongod<slaveshostname>[:port]/local
登录到slave从数据库节点的local数据库中。
master主节点的信息会存放在slave从节点的 sources集合中。这个是在启动从节点时,通过--source参数指定的。
如果启动时,没有指定--source参数,此时则可以往sources集合中增加一条包含主节点信息的记录,可以达到相同配置的效果。
$bin/mongo <slavehostname>/local
>db.sources.find(); 可查看sources中已有的信息。
>db.sources.insert( { host: <masterhostname>[ :port]} );
host:<masterhostname> 主节点的ip地址或域名全称,可跟上:port指定端口。
C 举例
简单的master\slave服务端配置的例子:
master(ip 192.168.1.1):
$/data/mongodb/bin/mongod--master --logpath=/data/mongodb/log/master.log --logappend --dbpath=/data/mongodb/data/db/master--port=10000 –directoryperdb
slave(ip 192.168.1.2)
$/data/mongodb/bin/mongod--slave --source=192.168.1.1:10000 --logpath=/data/mongodb/log/slave.log--logappend --dbpath=/data/mongodb/data/db/slave --port=20000 --slavedelay 10--directoryperdb
执行
$/data/mongodb/bin/mongod 192.168.1.1:10000
>db.printReplicationInfo()
可查看master状态。
执行
$/data/mongodb/bin/mongod 192.168.1.2:20000
>db.printSlaveReplicationInfo()
可查看slave连接以及状态。
D 添加或者移除
添加:
在已有的主从复制集群中,添加一个新的从节点,跟正常启用一个从节点的步骤一样,启用后,从节点会将主节点上所有的数据源(local除外)均复制一份,与oplog无关。
移除:
移除从节点,将从节点local数据源的sources集合中,将主节点的配置删除。同时,将主节点local数据源的slaves集合中,关于该从节点的配置删除。
操作如下
$bin/mongo <slavehostname>/local 登录到从节点的shell中
>db.sources.find(); 可查看sources中已有的信息
>db.sources.remove({host: <masterhostname>[ :port]})
>db.me.find() 查找该从节点的ObjectId,并记录下来
$bin/mongo <masterhostname>/local 登录到主节点的shell中
> db.slaves.find(); 可查看主节点slaves中已有的信息
>db.sources.remove({_Id:<从节点的ObjectId>})
E 注意点
如果一台从节点与主节点不同步,比如从节点的数据更新远远跟不上主节点(如,连续更新千万级以上的数据,但是,oplog更新日志的大小超过了oplogSize的设定值,更新日志的变化远远快于从节点的数据复制,从节点需要更新的日志记录已经在oplog中,被后来的更新日志记录所替代,最终使得更新日志不再可用)或者从节点中断之后重启但主节点中相关的数据更新日志却不可用了。这种情况下,复制操作将会终止,需要管理者的介入,看是否默认需要重启复制操作。管理者可以使用{resync:1} 命令重启复制操作,可选命令行参数--autoresync可使从节点在不同步情况发生10秒钟之后,自动重启复制操作。
一个从节点可以指定多个主节点,如果多个主节点具有名字相同的集合,那么从节点将试图合并这些集合,但是数据不能保证正确。
主节点宕机后,集群服务便不能再写入数据,只能通过从节点读取数据,从节点也不会取代主节点。而对于一些Driver客户端,如:java,主节点宕机后,连接便会出现异常。
2) 复制集模式(Replica Sets)
A 说明
复制集是一个带有自动故障转移的主从集群。是从现有的主从模式演变而来,增加了自动故障转移和节点成员自动恢复。
复制集模式中没有固定的主结点,在启动后,多个服务节点间将自动选举产生一个主结点。该主结点被称为primary,一个或多个从结点被称为secondaries。primary结点基本上就是master结点,不同之处在于primary结点在不同时间可能是不同的服务器。如果当前的主结点失效了,复制集中的其余结点将会试图选出一个新的主结点。
复制集模式的好处是,一切自动化。首先,复制集模式本身做了大量的管理工作,自动管理从节点,确保数据不会不一致。其次,主节点挂掉后,会自动判断集群中的服务器并进行故障转移,推举新的主节点。
一个复制集集群支持1-7台服务器,在一个复制集中各个服务器数据保持完全一致。
在一个复制集集群中,各个服务器有以下几种状态:
Ø Primary 主节点,一个复制集有且仅有一台服务器处于Primary状态,只有主节点才对外提供读写服务。如果主节点挂掉,复制集将会投票选出一个备用节点成为新的主节点。
Ø Secondary 备用节点,复制集允许有多台Secondary,每个备用节点的数据与主节点的数据是完全同步的。
Ø Recovering 恢复中,当复制集中某台服务器挂掉或者掉线后数据无法同步,重新恢复服务后从其他成员复制数据,这时就处于恢复过程,数据同步后,该节点又回到备用状态。
Ø Arbiter 仲裁节点,该类节点可以不用单独存在,如果配置为仲裁节点,就主要负责在复本集中监控其他节点状态,投票选出主节点。该节点将不会用于存放数据。如果没有仲裁节点,那么投票工作将由所有节点共同进行。
Ø Down 无效节点,当服务器挂掉或掉线时就会处于该状态。
复制集的从节点读请求,也是在各个Driver层设置slaveOk的值来实现的。
B 配置
复制集模式的集群配置(以三个节点举例,三个节点均在一台服务器上):
建立三个mongodb节点在该服务器上的数据库文件路径
mkdir –p/data/mongodb/data/db/r1
mkdir –p/data/mongodb/data/db/r2
mkdir –p/data/mongodb/data/db/r3
为复制集想好名称,通过名称,对复制集进行区分和引用。本配置示例中,将设定复制集名称为“rs”
设置复制集的三个mongodb节点,端口分别是10000、10001、10002
mongod --replSet rs --port 10000 --dbpath /data/mongodb/data/db/r1
mongod --replSet rs --port 10001 --dbpath /data/mongodb/data/db/r2
mongod --replSet rs --port 10002 --dbpath /data/mongodb/data/db/r3
其中,--replSet表示使用复制集模式,rs是该复制集模式集群的名称。复制集是自动检测,所以按照名称rs指定后,mongoDB将会自动判断及连接各个节点。
连接成功后,需要在shell下,对mongodb节点进行初始化,执行
$/data/mongodb/bin/mongolocalhost:10000 登录端口为10000的服务节点
> config = {_id: 'rs', members: [
{_id: 0, host: 'localhost:10000'},
{_id: 1, host: 'localhost:10001'},
{_id: 2, host: 'localhost:10002'}]
}
_id,设为复制集的名称
members是该复制集各个节点的地址数组信息。
可以随意登录任意一个节点进行初始化,以上的配置中,localhost,可以是服务器的ip地址,也可以是服务器的hostname。
而后执行
> rs.initiate(config);
使初始化配置生效。成功后,配置信息会在复制集各个节点传播并保存。
由此,完成该复制模式的配置。
注:所有的rs.xxx(),这是mongodb内部的方法。rs与命令里的db一样,是mongodb定义的对象,作用于复制集模式的管理。所以这里使用的rs.xxx()与复制集名称rs没有关系。
C local数据源结构
复制集各个节点启动成功并完成初始化配置后,每个节点都会拥有自己local数据源,该数据源与主从复制的local数据源原理相同,都为各个节点自己局部的数据库,负责保存集群、节点的状态、更新日志等。
按照上面配置的集群结果,假设10000端口的服务节点为主节点,那么,通过
$/data/mongodb/bin/mongolocalhost:10000/local
可登录到主节点的local数据库内,使用命令
> show collections
可查看local下的所有集合的信息,如图:
Ø oplog.rs集合,为复制集的变更操作日志记录,与主从复制模式的oplog集合相同。
Ø slaves集合,记录了复制集内,所有从节点的信息。
Ø system.replset集合,记录了该节点下,复制集的相关配置,如图:
图中信息展示的是复制集rs的配置信息。其中的version,表示版本信息,一旦复制集的配置发生变化并生效后,该版本信息会自动加1。
端口为10001和10002的服务节点为从节点,通过
$/data/mongodb/bin/mongolocalhost:10001/local
可登录到从节点的local数据库内,使用命令
> show collections
可查看local下的所有集合的信息,如图:
Ø me集合,记录了该从节点的ObjectId信息。
Ø oplog.rs集合,该集合没有任何记录。只有当主节点宕机后,该从节点被选为新的主节点后,该集合才开始工作,记录变更信息的日志。
Ø system.replset集合,记录了该节点下,复制集的相关配置,与主节点情况相同。
D 节点执行状态
Ø 查看主节点
在任意节点的shell下,使用
> rs.isMaster() //大小写必须相同。
可以查看该节点是否是主节点,以及复制集下各个节点的地址,
如,在主节点下:
setName表示为该复制集的名称。
ismaster表示是否是主节点,true为是,false为否。
secondary表示是否是从节点,true为是,false为否。
同样,在从节点下,会显示为:
primary表示现在主节点的地址信息。
Ø 查看节点状态
在任意节点的shell下,使用
> rs.status()
可看该复制集集群的状态。
主节点(端口为10000的节点服务)下:
从节点(端口为10001的节点服务)下:
myState与state字段,显示相关节点的读写状态,1表示为该节点当前可以进行读写,2表示为该节点不能读写。
health字段,显示相关节点的运行状态,1表示为该节点目前是正常的,0表示为该节点目前发生了异常。
如果端口为10001的服务节点宕机,那么,状态将变为:
如红框所示,health值变为了0,表示该复制集下,该节点已经发生了异常,不能正常工作。errmsg显示了异常的原因。
E 添加或者移除
添加:
在已有的复制集模式集群中,添加一个新的从节点,跟正常启用一个从节点的步骤一样,启用后,重新写入config的配置。
如:复制集有两台服务节点(端口为10000和10001),初始化配置为
> config = {_id: 'rs', members: [
{_id: 0, host: 'localhost:10000'},
{_id: 1, host: 'localhost:10001'}]
}
rs.initiate(config);
现在加入端口为10002的服务节点,
Ø 操作方式一
先启动端口为10002的mongodb服务,而后,重新写入config配置
> config = {_id: 'rs', members: [
{_id: 0, host: 'localhost:10000'},
{_id: 1, host: 'localhost:10001'},
{_id: 2, host: 'localhost:10002'}]
}
执行
>rs.reconfig(config);
shell中显示文本{“ok”: 1}表示添加新节点成功(ok为0时,表示不成功)。
Ø 操作方式二
还可以直接在shell中运行
> rs.add({_id: 2, host:'localhost:10002'})
shell中显示文本{“ok”: 1}添加新节点成功。
移除:
步骤与添加节点的方式一相似,修改config,将保留服务节点的配置写入,然后通过rs.reconfig(config)使配置重新生效即可。
所有的rs所支持的方法,可以通过 rs.help() 来查询。
3) 工作原理总结
一个MongoDB复制的配置至少由两台服务器(或节点)组成。一个是主节点,负责处理一般的客户请求,另一个是从节点,负责镜像存储在主节点上的数据。主节点保存一个它执行过的所有操作的记录(即local数据源中的oplog集合)。从节点周期性的轮询主节点上新的操作,然后把他们运用在备份的数据上。从而保证从节点的数据跟主节点一致性。
在主节点保存的操作记录为oplog(operation log)。Oplog中的每一个文档表示一个在主节点上执行的操作。每个文档主要包含4个key。
Ø ts :操作的时间戳。时间戳类型是一个用来跟踪操作是何时执行的一种内部类型。由四字节的时间戳(t为key)和四字节的增量计数器(i为key)组成。
Ø op:执行操作的类型,大小为1字节,例如,“i”代表insert,“n”代表没有操作等等(在主从模式中,会出现op为n的内容,在复制集模式下,不会出现)。
Ø ns:执行操作的集合名,即数据库名称+集合名称。
Ø o:执行操作的文档。
当一个从节点启动时,它将对主节点进行一次彻底的同步。从节点将复制主节点中每一个文档。同步完成后,从节点将查询主节点的oplog并且执行这些操作来保持数据的更新。
如果从节点的操作落后主节点太多,从节点处于out-of-sync状态,复制将被挂起。如果是主从模式,需要手动进行处理,如果是复制集模式,将由系统自动处理。为了避免这样的情况发生,需要设置一个足够大的oplog来存储主节点的操作
MongoDB分片及分布式集群
1) 简要说明
MongoDB在1.6版本中提供分片和复本集技术使得MongoDB真正具备了生产环境部署的能力。
MongoDB 包含一个自动分片模块 ("mongos")。自动分片可以用于构建一个大规模的可扩展的数据库集群,这个集群可以并入动态增加的机器,自动建立一个水平扩展的数据库集群系统,将数据库数据存储在sharding的各个节点上。
应用程序可以通过mongos process登陆shard集群,mongos process负责进行路由调度,将请求分发到合适的shardserver上。对应用来说shard端就像一个单节点数据库,但是数据库的存储空间无限扩大。假如要写大量数据到某个集合,这些数据会分发到多个sharedserver中,查询也是如此,因此查询效率会较高。
shard的分片单元是集合,而不是整个数据库。
2) 基本原理
A 工作原理
MongoDB分片的基本原理是把集合分成更小的chunks。这些chunks可以分散到不同的shards,每个shard负责集合的一部分。应用程序不会知道哪个分片有哪些数据,甚至不知道数据被放到了不同的shards。只有在shards的前端运行的路由进程mongos,才知道所有的数据放在哪,应用程序连接mongos,就可像平常一样发起查询。
B chunks
分割按有序分割方式,每个shard上的数据为某一范围的数据块(一个shard含有一个集合的多个chunk),故可支持指定分片的范围查询。数据块有指定的最大容量,一旦某个数据块的容量增长到最大容量时,这个数据块会切分成为两块;当分片的数据过多时,数据块将被迁移到系统的其他分片中。另外,新的分片加入时,数据块也会迁移。
C shard key
分片的关键在于shard key。通过shardkey划分每个shard上的chunk。
比如,根据集合的title字段做shardkey,分为三个shard,那么,分成A-F开头的文档chunk,G-N开头的文档chunk,及O-Z开头的文档chunk,将分别存储于三个shard中。当增加或者删除一个shard时,chunk块将重新划分,不过,mongodb会使每一个shard在负载和总量上保持平衡。一个高访问量的shard拥有的数据可能比一个低访问量的shard少。
对已经存在的集合,如果该集合都在一个shard上,增加一个新的shard,按照集合的title作为shardkey分片,那么,mongodb会按照title的开头字母将这个集合分成两个chunk,其中一个chunk将会被移动到新增的shard中。
被查询的数据,不论来自于1台shard,还是在所有shard中获取,都是由mongos来统一整理的。
3) 集群架构
在一个mongodb的集群中包括一些shard,mongos的路由进程,一个或多个config服务器。
A 架构图:
B shard
shard是一个包含集合数据子集的容器,一个shard是一个mongod服务器或者复制集。因此,即使一个shard由很多服务器组成,也只有一个是主节点(primary),其余的包含同样的数据。
C mongos
一个路由进程。仅是路由请求并收集响应,不存储任何数据或者配置信息。
可以有多个,相当于一个控制中心,负责路由和协调操作,使得集群像一个整体的系统。mongos可以运行在任何一台服务器上,有些选择放在shards服务器上,也有放在client 服务器上。mongos启动时需要从config servers上获取基本信息,然后接受client端的请求,路由到shards服务器上,然后整理返回的结果发回给client服务器。
C config server
存储集群的配置信息,包括分片和块数据信息,哪个块数据在哪个分片上。每个config server上都有一份所有块数据信息的拷贝,以保证每台config server上的数据的一致性。
4) 构建与管理
A 推荐
对于线上搭建分布式集群来说:
Ø 每个shard,推荐是一个mongod复制集,该复制集内的所有mongod服务节点,来自于不同ip的server。这样可以保证,复制集内某个mongod服务节点宕掉,或者server宕掉,都不会影响该shard的数据更新与读取。
Ø Config server 可以设置多台,1台使用,其它的备用。
Ø 多个mongos服务器。
B 详细配置
以localhost为例子中的服务器地址,实际操作中,可以选择内网中任意ip的服务器中启用这些mongdb的进程。
shard两组:
一组复制集模式:localhost:10000和localhost:10001
一组普通单台mongod服务: localhost:10002
configserver 三个:
localhost:20001
localhost:20002
localhost:20003
mongos一个:
localhost:30000
a) 配置config server
建立3个config server所使用的文件目录
mkdir –p /data/mongodb/data/db/c1
mkdir –p /data/mongodb/data/db/c2
mkdir –p /data/mongodb/data/db/c3
启动3个config server
mongod --configsvr --dbpath /data/mongodb/data/db/c1 --port 20001
mongod --configsvr --dbpath /data/mongodb/data/db/c2 --port 20002
mongod --configsvr --dbpath /data/mongodb/data/db/c3 --port 20003
b) 配置mongos
启动mongos,指向所有的config server服务
mongos --configdb localhost:20001, localhost:20002, localhost:20003 --port30000
多台config server中间使用 ”,” 隔开。
可以使用相同的命令,运行多个mongos 。在实际应用中,可以对每个应用程序服务器都设置一个局部的mongos供其使用。如果mongos宕机,那么只会影响到一个应用程序。
c) 启动shard
建立3个数据库文件路径
mkdir –p/data/mongodb/data/db/s1
mkdir –p/data/mongodb/data/db/s2
mkdir –p/data/mongodb/data/db/s3
启动第一组shard,该组为复制集
mongod--shardsvr --port 10000 --replSet sd --dbpath /data/mongodb/data/db/s1
mongod--shardsvr --port 10001 --replSet sd --dbpath /data/mongodb/data/db/s2
在shell中执行初始化
/data/mongodb/bin/mongolocalhost:10000 登录到端口为10000的服务的shell中
config = {_id: 'sd', members: [
{_id: 0, host: 'localhost:10000'},
{_id: 1, host: 'localhost:10001'}]
}
rs.initiate(config)
启动第二组shard,该组为单台服务
mongod--shardsvr --port 10002 --dbpath /data/mongodb/data/db/s3
d) 加入shard
登录到mongos所在服务的shell中
/data/mongodb/bin/mongo localhost:30000/admin
加入第一组分片
db.runCommand({addshard:”sd/localhost:10000,localhost:10001”,allowLocal:true})
加入第二组分片
db.runCommand({addshard:”localhost:10002”,allowLocal:true})
注:allowLocal:true,只有在localhost上运行时,才需要这个配置,如果localhost换成具体的ip地址,那么,这个配置不需要。
在shell中,配置成功后,如下图所示:
e) 指定数据库分片
在mongos所在服务的shell中,执行命令:
db.runCommand( {enablesharding : “<dbname>” } );
dbname表示数据库名。
通过执行以上命令,可以让数据库跨shard,如果不执行这步,数据库只会存放在一个shard。一旦激活数据库分片,数据库中不同的collection将被存放在不同的shard上,但一个collection仍旧存放在同一个shard上。
在本例中,对数据库content进行分片,则命令为
db.runCommand({ enablesharding : “content” } );
执行成功后,为下图所示:
f) 指定集合分片
指定对某一个集合进行分片存储,需要给集合指定一个分片key,在mongos所在服务的shell中,执行命令:
db.runCommand( {shardcollection : “<namespace>”,key : <shardkeypatternobject> });
namespace表示集合的含命名空间的全名,即:数据库名.集合名。
Shardkeypatternobject指定的分片键。
注意:分片的集合只能有一个在分片key上的唯一索引,其它唯一索引不被允许,因为集合数据分布在多个shard中,其它唯一索引无法保证。
在本例中,对数据库content的col集合进行分片,以 _id 作为分片键,则命令为
db.runCommand( {shardcollection : “content.col”,key : {_id:1} });
其中,_id的值,1代表升序,-1代表降序
执行成功后,为下图所示:
C 集群中shard的添加和移除
Ø 添加
在已存在的集群中,添加新的shard,只需要重复上述c) —— f)的操作即可。
Ø 移除
登录到mongos所在服务的shell中,使用命令
db.runCommand({removeshard:”server_ip:port”})
如,删除第二组分片,执行db.runCommand({removeshard:”localhost:10002”})即可。
D 管理
分片信息保存config server的config数据库中,可以直接通过mongos进程进行访问。
登录到mongos所在服务的shell中,使用
>use config
可以进入到config数据库。可在此数据库查看集群相关信息。
Ø 查看所有分片信息
>db.shards.find()
_id:在添加分片时,设定好的分片的名称。上图,sd是自定义的复制集的名称,shard0000是添加时,系统指定的名称。
Ø 查看包含在shard中的所有数据库的信息
>db.databases.find()
_id:表示数据库的名字
partitioned:如果为true,则数据库已分片
primary:指明这个数据库的home,即开始创建数据文件的地方,无论是否分片。
Ø 查看所有chunks集合信息
>db.chunks.find()
上图表示,当前的chunk,在名为shard0000的分片上。
等到文档足够多的时候,就会被分成多个chunk,下图中,是对abc_Content集合的chunk分析,共添加了800万的数据:
可看到,800w的数据被分成了4个chunk,每个chunk都有其_id的范围min和max。
Ø 查看集合的概况,包含shard、database、chunks信息
>db.printShardingStatus()
Ø 查看集群内集合的信息
在mongs 的shell里,使用content数据库,可以查看集合的状态。
>usecontent (content,具体分片的数据库)
>db.col.stats() (col,具体被分片的集合)
使用这个命令可以查看具体集合的chunk数、在每个分片的数据size以及数据文件的大小等等信息。
集群架构图:
好了,到此MongoDB搭建文档v1.0的到此结束了!!!对于存在的问题可以在163邮箱中进行反馈,我将在下次版本中进行更新!上述代码都基本进行了测试,请了解熟悉了点Mongodb 在进行操作以免遇到一些很常见且不该犯的错误,谢谢!