1、概述
MongoDB在1.6版本中提供分片和复本集技术使得MongoDB真正具备了生产环境部署的能力。
MongoDB 包含一个自动分片模块 ("mongos")。自动分片可以用于构建一个大规模的可扩展的数据库集群,这个集群可以并入动态增加的机器,自动建立一个水平扩展的数据库集群系统,将数据库数据存储在sharding的各个节点上。
应用程序可以通过mongos process登陆shard集群,mongosprocess负责进行路由调度,将请求分发到合适的shard server上。对应用来说shard 端就像一个单节点数据库,但是数据库的存储空间无限扩大。假如要写大量数据到某个集合,这些数据会分发到多个shared server中,查询也是如此,因此查询效率会较高。
shard的分片单元是集合,而不是整个数据库。
2、原理
(1)工作原理
MongoDB分片的基本原理是把集合分成更小的chunks。这些chunks可以分散到不同的shards,每个shard负责集合的一部分。应用程序不会知道哪个分片有哪些数据,甚至不知道数据被放到了不同的shards。只有在shards的前端运行的路由进程mongos,才知道所有的数据放在哪,应用程序连接mongos,就可像平常一样发起查询。
(2)chunks
分割按有序分割方式,每个shard上的数据为某一范围的数据块(一个shard含有一个集合的多个chunk),故可支持指定分片的范围查询。数据块有指定的最大容量,一旦某个数据块的容量增长到最大容量时,这个数据块会切分成为两块;当分片的数据过多时,数据块将被迁移到系统的其他分片中。另外,新的分片加入时,数据块也会迁移。
(3) shared key
分片的关键在于shard key。通过shard key划分每个shard上的chunk。比如,根据集合的title字段做shard key,分为三个shard,那么,分成A-F开头的文档chunk,G-N开头的文档chunk,及O-Z开头的文档chunk,将分别存储于三个shard中。当增加或者删除一个shard时,chunk块将重新划分,不过,mongodb会使每一个shard在负载和总量上保持平衡。一个高访问量的shard拥有的数据可能比一个低访问量的shard少。
对已经存在的集合,如果该集合都在一个shard上,增加一个新的shard,按照集合的title作为shard key分片,那么,mongodb会按照title的开头字母将这个集合分成两个chunk,其中一个chunk将会被移动到新增的shard中。
被查询的数据,不论来自于1台shard,还是在所有shard中获取,都是由mongos来统一整理的。
3、架构图
shard是一个包含集合数据子集的容器,一个shard是一个mongod服务器或者复制集。因此,即使一个shard由很多服务器组成,也只有一个是主节点(primary),其余的包含同样的数据。
mongos一个路由进程。仅是路由请求并收集响应,不存储任何数据或者配置信息。可以有多个,相当于一个控制中心,负责路由和协调操作,使得集群像一个整体的系统。mongos可以运行在任何一台服务器上,有些选择放在shards服务器上,也有放在client服务器上。mongos启动时需要从config servers上获取基本信息,然后接受client端的请求,路由到shards服务器上,然后整理返回的结果发回给client服务器。
configserver存储集群的配置信息,包括分片和块数据信息,哪个块数据在哪个分片上。每个config server上都有一份所有块数据信息的拷贝,以保证每台config server上的数据的一致性。
4、搭建过程
同样在一台机器上实现。
(1)开启config服务器 C盘:2222
(2)开启mongos服务器 D:3333,指定config服务器
(3)启动mongod服务器
添加分片,开启E、F盘的mongodb,端口分别为4444、5555。如下:
(4)服务配置
从架构图中可以看出,client直接和mongos服务器打交道,即我们需要连接mongos服务器,然后把4444和5555两个分片交给mongos。添加分片命令:
addshard()。
连接3333服务器,以admin身份:
添加分片:
两个shard已经集群,但是mongos不知道该如何切分数据,需要设置片键,分两个步骤:
第一:开启数据库分片功能,enablesharding()
第二:指定集合中分片的片键。
上图中,开启test数据库的分片功能。通知指定片键为emp的name字段。
(5)查看效果
通过mongos(3333)向mongodb插入10000条记录,通过printShardingStattus()命令查看mongodb的数据分片情况。
通过命令查看:
参数说明:
第一:shards 从图中可以看到:分成两片了,shard0000和shard0001。
第二:databases:partitioned表示是否分区,可以看到test已分区。
第三:chunks:分成了一段。都在shard0000。
当插入百万时,会明显看到两个shard都有数据,如下:
其中shard0001分成了2块,shard0000分成了6块。
在3333上调用db.emp.stats()可以看到如下内容:
5、管理维护sharding
(1)列出所有的Shard Server
(2)查看Sharding信息
(3)查看是否是Sharding
(4)对现有表进行sharding
对emp2表进行sharding,步骤如下:
可以看到sharded值为false,即未shard。
执行如下命令:
再次查看:
可以看到shared参数值变为true了。
(5)新增shard server
在mongos下,以admin登录,同时切换到admin数据库,执行如下命令:
db.runCommand({addshard:”127.0.0.1:6666”}).
(6)移除shard server
在mongos下,以admin登录,同时切换到admin数据库,执行如下命令:
db.runCommand({removeshard:”127.0.0.1:6666”}).