MongoDB的集群模式有三种:
- 主从(Master-Slaver),MongoDB 3.6彻底废弃
- 副本集(Replica Set)
- 分片(Sharding)
本章主要讲述分片(Sharding))。
一、分片介绍
1.1 什么是分片
分片是指将数据拆分,将其分散存放在不同的机器上的过程。有时也用分区来表示这个概念。将数据分散在不同的机器上,不需要功能强大的大型计算机就可以存储更多的数据,处理更大的负载。
1.2 为什么使用分片
- 副本集具有节点数量限制
- 增加单台服务器可用的磁盘空间
- 减轻单台服务器的负载
- 处理单个mongod无法承受的吞吐量
1.3 分片原理
MongoDB 支持自动分片,可以使数据库架构对应用程序不可见,也可以简化系统管理,对程序而言,好像始终在使用一个单机MongoDB服务器一样。另一方面,MongoDB 自动处理数据在分片上的分布,也更容易添加和删除分片。
下面是MongoDB 分片集群架构图:
- Router(mongos):数据库集群的请求入口,所有的请求都通过Router(mongos)进行协调,不需要在应用程序添加一个路由选择器,Router(mongos)就是一个请求分发中心,它负责吧应用程序的请求转发到对应的Shard服务器上。通常在生产环境下有多个Router(mongos)作为请求的入口,防止其中一个挂掉所有的mongodb无法使用;
- Config Server:配置服务器。存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。Router(mongos) 第一次启动或者关掉重启就会从 config server 加载配置信息,以后如果配置服务器信息变化会通知到所有的 Router(mongos) 更新自己的状态,这样 Router(mongos) 就能继续准确路由。在生产环境通常有多个 config server 配置服务器,防止数据丢失;
- Shared:分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程。将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。基本思想就是将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分,最后通过一个均衡器来对各个分片进行均衡(数据迁移)。
注意
复制是让多台服务器都拥有同样的数据副本每台服务器都是其它服务器的镜像,而每个分片存储不同的数据子集。
二、示例
下面我在一台机器上使用不同的端口演示分片集群的部署。
ip | 端口 | 角色 |
---|---|---|
127.0.0.1 | 27010 | shard |
127.0.0.1 | 27011 | shard |
127.0.0.1 | 27012 | shard |
127.0.0.1 | 27020 | config server |
127.0.0.1 | 40000 | Route |
2.1 启动 Shard Server
$ mkdir -p D:/dev/tools/apps/MongoDB/Server/3.2/data/shard/s0
$ mkdir -p D:/dev/tools/apps/MongoDB/Server/3.2/data/shard/s1
$ mkdir -p D:/dev/tools/apps/MongoDB/Server/3.2/data/shard/s2
$ mkdir -p D:/dev/tools/apps/MongoDB/Server/3.2/data/shard/s3
$ mkdir -p D:/dev/tools/apps/MongoDB/Server/3.2/log
$ ./mongod --port 27010 --dbpath D:/dev/tools/apps/MongoDB/Server/3.2/data/shard/s0 --logpath D:/dev/tools/apps/MongoDB/Server/3.2/log/s0.log --logappend --shardsvr
$ ./mongod --port 27011 --dbpath D:/dev/tools/apps/MongoDB/Server/3.2/data/shard/s1 --logpath D:/dev/tools/apps/MongoDB/Server/3.2/log/s1.log --logappend --shardsvr
$ ./mongod --port 27012 --dbpath D:/dev/tools/apps/MongoDB/Server/3.2/data/shard/s2 --logpath D:/dev/tools/apps/MongoDB/Server/3.2/log/s2.log --logappend --shardsvr
2.2 启动 Config Server
$ mkdir -p D:/dev/tools/apps/MongoDB/Server/3.2/data/config
$ ./mongod --port 27020 --dbpath D:/dev/tools/apps/MongoDB/Server/3.2/data/config --logpath D:/dev/tools/apps/MongoDB/Server/3.2/log/config.log --logappend --shardsvr
2.3 启动 Route
$ ./mongos --port 40000 --configdb localhost:27020 --logpath D:/dev/tools/apps/MongoDB/Server/3.2/log/route.log --chunkSize 500
chunkSize这一项是用来指定chunk的大小的,单位是MB,默认大小为200MB.
2.4 配置分片
添加分片
$ ./mongo admin --port 40000
MongoDB shell version: 3.2.7
connecting to: 127.0.0.1:40000/admin
> db.runCommand({ addshard:"localhost:27010" })
{ "shardAdded" : "shard0000", "ok" : 1 }
> db.runCommand({ addshard:"localhost:27011" })
{ "shardAdded" : "shard0001", "ok" : 1 }
> db.runCommand({ addshard:"localhost:27012" })
{ "shardAdded" : "shard0002", "ok" : 1 }
查看分片
> db.runCommand({listshards:1})
{
"shards" : [
{
"_id" : "shard0000",
"host" : "localhost:27010"
},
{
"_id" : "shard0001",
"host" : "localhost:27011"
},
{
"_id" : "shard0002",
"host" : "localhost:27012"
}
],
"ok" : 1
}
激活分片
设置分片存储的数据库
> db.runCommand({"enablesharding":"test"})
{ "ok" : 1 }
表分片:要使单个collection也分片存储,需要给collection指定一个分片key,通过以下命令操作:
> db.runCommand({ shardcollection: "test.log", key: { id:1,time:1}})
{ "collectionsharded" : "test.log", "ok" : 1 }
完成数据mongo分片的搭建了。
2.5 测试分片配置结果
插入数据
$ ./mongo admin --port 40000
MongoDB shell version: 3.2.7
connecting to: 127.0.0.1:40000/admin
> use log
> for (var i = 1; i <= 10; i++) db.log.save({id:i,"time":new Date()});
查看分片情况
> db.log.stats()
{
"sharded" : true,
"capped" : false,
"ns" : "test.log",
"count" : 7633,
"size" : 366384,
"storageSize" : 245760,
"totalIndexSize" : 364544,
"indexSizes" : {
"_id_" : 139264,
"id_1_time_1" : 225280
},
"avgObjSize" : 48.0,
"nindexes" : 2,
"nchunks" : 3,
"shards" : {
"shard0000" : {
"ns" : "test.log",
"count" : 2,
"size" : 96,
...
"ok" : 1.0
},
"shard0001" : {
"ns" : "test.log",
"count" : 7602,
"size" : 364896,
...
"ok" : 1.0
},
"shard0002" : {
"ns" : "test.log",
"count" : 29,
"size" : 1392,
...
"ok" : 1.0
}
},
"ok" : 1.0
}
部分数据省略。可以看到三个分片,各自的count就是存储了数据的大小。