首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

MongoDB 分片Sharding 提案 及 chunks块 和 片键分析

2013-10-08 
MongoDB 分片Sharding 方案 及 chunks块 和 片键分析--------------------------------------------0,创建

MongoDB 分片Sharding 方案 及 chunks块 和 片键分析
--------------------------------------------
0,创建3个Shard Server
//创建数据库,日志文件
[root@localhost ~]# mkdir -p /data/shard/s0[root@localhost ~]# mkdir -p /data/shard/s1[root@localhost ~]# mkdir -p /data/shard/s2[root@localhost ~]# mkdir -p /data/shard/log

Shard Sever 1 : 38010Shard Sever 2 : 38011Shard Sever 3 : 38012
Config Server : 40000Route Process : 50000

1,建立3个数据库作为3个分片
这是里为方便看日志,直接在命令行输出查看
/Apps/mongo/bin/mongod --dbpath=/data/shard/s0 --shardsvr --port 38010 --directoryperdb --rest
/Apps/mongo/bin/mongod --dbpath=/data/shard/s1 --shardsvr --port 38011 --directoryperdb --rest
/Apps/mongo/bin/mongod --dbpath=/data/shard/s2 --shardsvr --port 38012 --directoryperdb --rest

(--directoryperdb那你每个库的文件会单独放在一个文件夹里)

正式运行要后台运行就用下面的:
/Apps/mongo/bin/mongod --dbpath=/data/shard/s0 --shardsvr --port 38010 --directoryperdb --logpath=/data/shard/log/s0.log --logappend --fork --rest
/Apps/mongo/bin/mongod --dbpath=/data/shard/s1 --shardsvr --port 38011 --directoryperdb --logpath=/data/shard/log/s1.log --logappend --fork --rest
/Apps/mongo/bin/mongod --dbpath=/data/shard/s2 --shardsvr --port 38012 --directoryperdb --logpath=/data/shard/log/s2.log --logappend --fork --rest



--------------------------------------------1,启动Config Server, Config Server : 40000
//创建数据库,日志文件
mkdir -p /data/shard/config
/Apps/mongo/bin/mongod --dbpath /data/shard/config --configsvr --port 40000 --directoryperdb --rest
正式运行要后台运行就用下面的:
/Apps/mongo/bin/mongod  --dbpath /data/shard/config --configsvr --port 40000  --logpath=/data/shard/log/config.log --fork --directoryperdb --rest
--------------------------------------------

2,启动Route Process,Route Process : 50000
/Apps/mongo/bin/mongos --port 50000 --configdb 127.0.0.1:40000 --chunkSize 1 
--chunkSize 1 (MB)指定分片的最小单位容量,这里设置1M,方便查看效果 
正式运行要后台运行就用下面的:
/Apps/mongo/bin/mongos --port 50000 --configdb 127.0.0.1:40000 --chunkSize 50 --logpath=/data/shard/log/route.log --fork
--------------------------------------------
如图:此时并未加入任何片到Sharding集群中,可以看到,对于Sharding集群中,其admin数据库是不分片的方式存放在Config Server中的!MongoDB 分片Sharding 提案 及 chunks块 和 片键分析

-----------------------------------------------
3,连接到mongos配置Sharding
用Mongo Shell 登录 Route Process
/Apps/mongo/bin/mongo --port 50000 
use admin (记得执行这一点,切换到admin数据库)
//添加分片节点,每个分片都是一个副本集db.runCommand({addshard:"127.0.0.1:38010",allowLocal:true})db.runCommand({addshard:"127.0.0.1:38011",allowLocal:true})db.runCommand({addshard:"127.0.0.1:38012",allowLocal:true})

allowLocal:true仅仅开发时才将分片配置到本地,生产时不能这样
-----------------------------------------------如图:配置信息被添加到Config Server的config数据库的shards集合中:MongoDB 分片Sharding 提案 及 chunks块 和 片键分析-------------------------------------------
4,配置数据库mydb,启用分片
use admin
db.runCommand({enablesharding:"mydb"})
如图: mydb启用分片后,其基片(primary shard server)是shard0000MongoDB 分片Sharding 提案 及 chunks块 和 片键分析

mydb被配置成启用分片后,配置信息是存放在配置服务器的数据库config的databases集合里!
-------------------------------------------
5,设置要分片的集合:使集合users以片键_id来分片
db.runCommand({shardcollection:"mydb.users",key:{_id:1}})
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析mydb的users集合被配置成启用分片后,配置信息是存放在配置服务器的数据库config的collections集合里!
--------------------------------------------
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
这里可以看到,路由服务器是不会存放配置信息(不用配置dbpath也是这个原因,但会缓存配置服务器上的配置!)

--------------------------------------------
6,Sharding Cluster的数据插入的测试(递增片键方式)
use admin
db.runCommand({shardcollection:"mydb.users",key:{_id:1}})
use mydb
测试插入60万条数据for(var i=1; i<=600000; i++) db.users.insert({age:i,name:"mary",addr:"guangzhou",country:"China"})


然后等几分钟,集合users的数据就均匀分布到各个分片,分片完成
1,先看看每个trunk,这里测试需要,设置了1MB/trunk,如图MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
每个trunk记录了片键的范围,还有所在的片的名称

图:已插入21万个文档,主要在shard0002插入MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
图:已插入28万个文档,之后到主要向shard0001插入MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
图:已插入40万个文档,之后到主要向shard0002插入MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
图:已插入61万个文档?,主要向shard0000插入
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
图:60万个文档全部正常插入完成,此时数据不太均匀MongoDB 分片Sharding 提案 及 chunks块 和 片键分析

以上都是5分钟以内的分片情况,过了几小时后,每个Shard Server的chunks块数量是相同的,证明mongos路由服务器会实时对各分片进行负载均衡!MongoDB 分片Sharding 提案 及 chunks块 和 片键分析

因为Sharding key 是ObjectIdMongoDB 分片Sharding 提案 及 chunks块 和 片键分析这里ObjectId就像一个递增片键,插入时不能均匀地路由到各片,此时写入的负载不均匀,这里60万个文档写入完后在各片分布不太均匀,所以mongos路由会在后台对各片进行负载均衡,直至各片的chunks块数量相等!---------------------------------------------------------B:向已有42个块且有数据的Sharding Cluster插入60万条递增键的文档:

MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
以上是3分钟之内的,刚刚到60万条插入完毕的时刻!以下是10分钟稳定后:MongoDB 分片Sharding 提案 及 chunks块 和 片键分析

刚开始插入的37万条主要集中在shard0001上,然后分别有18万条和5万条插入到shard0002和shard0000,时间上插入得不太均匀!因为这是递增键,操作往往会集中在某个块和某个片上!

--------------------------------------------
7,Sharding Cluster的数据插入的测试(随机片键方式)
use admin
db.runCommand({shardcollection:"mydb.peoples",key:{ram:1}})  

use mydb
测试插入60万条数据for(var i=1; i<=600000; i++) db.peoples.insert({name:"irelandken__ZHEN",age:i,addr:"guangzhou",country:"China", ram : Math.random()})

这里我们有一个随机小数[0--1)来作为片键,
3分钟后:非常不均匀!MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
15分钟后:均匀了!MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
怎么用随机片键还是会出现这种情况呢??刚插入数据还是分布得那么不均匀!因为刚开始里,配置服务器里没有chunks块,第一个无限大的块位于基片上,而后来边向数据库插入数据边分裂出更细的chunks块,这时分裂出的块主要分布在基片shard000上所以导致插入操作集中在基片上执行!
那现在已经有83个chunks的情况下再插入60万条呢?觉得这次一定会很均匀
再插入60万条数据for(var i=1; i<=600000; i++) db.peoples.insert({name:"ZHEN",age:i,addr:"zhuhai",country:"China", ram : Math.random()})
60万个文档刚插入完成的情况:MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
看上图,猜对了,终于看到了随机片键的效果!!因为3个分片上的chunks块是均匀的,因为再产生的60万个文档的片键也是随机键将会均匀地命中3个片的chunks!   mongos路由服务器的想法应该是如果分片上的负载不均衡,就会调整各分片,直至各分片的chunks块数量大致相等!
现在,我们将这个集合清空,再次测试插入60万条随机键的文档use mydb
db.peoples.remove()
清空这个集合(只要不删除这个集合)是不会删除已经存在的153个chunks块的!MongoDB 分片Sharding 提案 及 chunks块 和 片键分析

向已有153个chunks块的空集合插入60万个随机键的文档for(var i=1; i<=600000; i++) db.peoples.insert({name:"jack",age:i,addr:"Beijing",country:"China", ram : Math.random()})
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析

MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析

MongoDB 分片Sharding 提案 及 chunks块 和 片键分析
MongoDB 分片Sharding 提案 及 chunks块 和 片键分析

可见,整个插入过程是相当均匀!而块的数量仅仅增加了2块,就是说60万个文档几乎全部"命中"已存在的各个块!
-------------------------------------------------------
8,测试6和7的小结
1:如果刚开始对于新的集合,配置服务器里没有该集合的chunks块信息,这里无论是递增键或随机键,  数据的插入过程也不会均匀,甚至有可能集中在某台机器上,然后mongos再来执行负载均衡
2: mongos路由会在后台对各片进行负载均衡,直至各片的chunks块数量相等!
3: 对于负载均衡的Sharding Cluster(各片的chunks块数量相等),对于随机键的操作会非常有效,基本整个过程是很均匀的    而此时递增键的操作还是会出现严重的负载不均衡的情况!


--------------------------------------------
6,移除Shard Server,回收数据

db.runCommand({"removeshard" : "127.0.0.1:38010"})

因为127.0.0.1:38010是数据库test和mydb的Primary片"primary" : "shard0000"基片,所以要手动移动数据库的基片
如:
/* 1 */{  "_id" : "test",  "partitioned" : true,  "primary" : "shard0000"}
/* 2 */{  "_id" : "mydb",  "partitioned" : true,  "primary" : "shard0000"}
手动修改数据库test的基片,改为127.0.0.1:38011执行: mongos> db.runCommand({"moveprimary" : "test","to" : "127.0.0.1:38011"}){ "primary " : "shard0001:127.0.0.1:38011", "ok" : 1 }
手动修改数据库test的基片,改为127.0.0.1:38011执行: mongos> db.runCommand({"moveprimary" : "mydb","to" : "127.0.0.1:38011"}){ "primary " : "shard0001:127.0.0.1:38011", "ok" : 1 }

依赖要删除的片的关系全部删除后,再找执行一次:db.runCommand({"removeshard" : "127.0.0.1:38010"})


mongos> db.runCommand({"removeshard" : "127.0.0.1:38010"}){        "msg" : "removeshard completed successfully",        "state" : "completed",        "shard" : "shard0000",        "ok" : 1}
mongos分回收该片的数据,平均到其它片,然后在分片集群中移除该片!
多次调用这一句,中间可以看到进行的进度!此操作对用户完全透明,不需要停机操作!
--------------------------------------------
7,新增Shard Server
连接到mongos
因为在各分片里存在数据库test和mydb的集合的分片,而规定加入的新mongod不能含有相同的数据库(试想如果加入的数据库含有数据库mydb,且其中含有一定数量的数据,此数据一定要被删除)向mongos新加入的Shard Server一定不能含有与其它片相同的数据库的!
use admin
db.runCommand({addshard:"127.0.0.1:38010",allowLocal:true})

新的片被加入后,mongos再次将次执行负载均衡,将数据均匀到各片中!

--------------------------------------------
从各部分的LOG来看,只有节点Shard Server和路由Route Process是比较"忙"的,Config Server好像仅仅只是同步Route Process的配置而已,因为路由Route Process不会持久化数据,Config Server为它存放配置感觉路由Route Process是一个Facade,外部看来是一个数据库

1楼mask_243小时前
新增Shard Server

热点排行