读书人

【转】MongoDB Replica Sets + Shardi

发布时间: 2013-10-08 16:18:21 作者: rapoo

【转】MongoDB Replica Sets + Sharding 方案 及 chunks块 和 片键分析
创建第一个replset---------------------------------------------------------------------------创建目录mkdir -p /data/replset_sharding/replset1/r0mkdir -p /data/replset_sharding/replset1/r1mkdir -p /data/replset_sharding/replset1/r2mkdir -p /data/replset_sharding/replset1/log??改用下面的就行了(这是里为方便看日志,直接在命令行输出查看)?/Apps/mongo/bin/mongod --dbpath?/data/replset_sharding/replset1/r0?--replSet? replset1?--port 18010?--directoryperdb --rest?/Apps/mongo/bin/mongod --dbpath?/data/replset_sharding/replset1/r1 --replSet? replset1?--port 18011?--directoryperdb --rest?/Apps/mongo/bin/mongod --dbpath?/data/replset_sharding/replset1/r2 --replSet? replset1?--port 18012?--directoryperdb --rest??初始化复本集:?/Apps/mongo/bin/mongo --port 18010?config_replset1?= {_id:"replset1",members:[{_id:0,host:"127.0.0.1:18010",priority:4},{_id:1,host:"127.0.0.1:18011",priority:2},{_id:2,host:"127.0.0.1:18012",arbiterOnly : true}]}?注意arbiter仲裁节点只投票,不接收复制的数据!??rs.initiate(config_replset1);---------------------------------------------------------------------------?创建第二个replset---------------------------------------------------------------------------创建目录mkdir -p /data/replset_sharding/replset2/r0mkdir -p /data/replset_sharding/replset2/r1mkdir -p /data/replset_sharding/replset2/r2mkdir -p /data/replset_sharding/replset2/log??改用下面的就行了(这是里为方便看日志,直接在命令行输出查看)?/Apps/mongo/bin/mongod --dbpath?/data/replset_sharding/replset2/r0?--replSet? replset2?--port 28010?--directoryperdb --rest?/Apps/mongo/bin/mongod --dbpath?/data/replset_sharding/replset2/r1 --replSet? replset2?--port 28011?--directoryperdb --rest?/Apps/mongo/bin/mongod --dbpath?/data/replset_sharding/replset2/r2 --replSet? replset2?--port 28012?--directoryperdb --rest??初始化复本集:?/Apps/mongo/bin/mongo --port 28010?config_replset2?= {_id:"replset2",members:[{_id:0,host:"127.0.0.1:28010",priority:4},{_id:1,host:"127.0.0.1:28011",priority:2},{_id:2,host:"127.0.0.1:28012",arbiterOnly : true}]}?注意arbiter仲裁节点只投票,不接收复制的数据!??rs.initiate(config_replset2);---------------------------------------------------------------------------创建第三个replset---------------------------------------------------------------------------创建目录mkdir -p /data/replset_sharding/replset3/r0mkdir -p /data/replset_sharding/replset3/r1mkdir -p /data/replset_sharding/replset3/r2mkdir -p /data/replset_sharding/replset3/log??改用下面的就行了(这是里为方便看日志,直接在命令行输出查看)?/Apps/mongo/bin/mongod --dbpath?/data/replset_sharding/replset3/r0?--replSet? replset3?--port 38010?--directoryperdb?--rest?/Apps/mongo/bin/mongod --dbpath?/data/replset_sharding/replset3/r1 --replSet? replset3?--port 38011?--directoryperdb?--rest?/Apps/mongo/bin/mongod --dbpath?/data/replset_sharding/replset3/r2 --replSet? replset3?--port 38012?--directoryperdb?--rest??初始化复本集:?/Apps/mongo/bin/mongo --port 38010?config_replset3?= {_id:"replset3",members:[{_id:0,host:"127.0.0.1:38010",priority:4},{_id:1,host:"127.0.0.1:38011",priority:2},{_id:2,host:"127.0.0.1:38012",arbiterOnly : true}]}?注意arbiter仲裁节点只投票,不接收复制的数据!??rs.initiate(config_replset3);---------------------------------------------------------------------------???---------------------------------------------------------------------------?//创建数据库,日志文件??mkdir -p /data/replset_sharding/log???--------------------------------------------1,启动Config Server, Config Server : 40000,40001,40002?mkdir -p /data/replset_sharding/config0mkdir -p /data/replset_sharding/config1mkdir -p /data/replset_sharding/config2?/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/config0 --configsvr --port 40000 --directoryperdb?--rest/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/config1 --configsvr --port 40001 --directoryperdb?--rest/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/config2 --configsvr --port 40002 --directoryperdb?--rest?正式运行要后台运行就用下面的:?/Apps/mongo/bin/mongod? --dbpath /data/replset_sharding/config --configsvr --port 40000??--logpath /data/replset_sharding/log/config.log --fork --directoryperdb?--rest?------------------------------------------------------以上的3个Config Server里存放集群分片的配置信息,如果Config Server出问题是无法正常启动集群的!配置服务器使用的是两步提交机制(而不是普通MongoDB副本集的异步复制),因为两步提交是实时的一致性,而异步复制是最终一致性!?两步提交机制确保3台机的配置是一致的,如果有某台配置服务器宕机了,那集群配置信息将是只读的!?客户端还是能够读取集群的数据,还有能有限地更新集群的数据(只要不需要修改配置服务器的配置,如chunks块的修改,或片键的修改)??【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?PS:整个集群的admin数据库是存放在Config Sever中的,而3台Config Server不止数据库config是同步的,而且数据库admin也是同步的??--------------------------------------------??2,启动Route Process,Route Process : 50000?/Apps/mongo/bin/mongos --port 50000 --configdb 127.0.0.1:40000,127.0.0.1:40001,127.0.0.1:40002?--chunkSize 1??--chunkSize 1 (MB)指定分片的最小单位容量,这里设置1M,方便查看效果??正式运行要后台运行就用下面的:?/Apps/mongo/bin/mongos --port 50000 --configdb 127.0.0.1:40000 --chunkSize 50 --logpath=/data/replset_sharding/log/route.log --fork?--------------------------------------------?3,连接到mongos配置Sharding?用Mongo Shell 登录 Route Process?/Apps/mongo/bin/mongo --port 50000??use admin (记得执行这一点,切换到admin数据库)?//添加分片节点,每个分片都是一个副本集db.runCommand({addshard:"replset1/127.0.0.1:18010,127.0.0.1:18011,127.0.0.1:18012",allowLocal:true})db.runCommand({addshard:"replset2/127.0.0.1:28010,127.0.0.1:28011,127.0.0.1:28012",allowLocal:true})db.runCommand({addshard:"replset3/127.0.0.1:38010,127.0.0.1:38011,127.0.0.1:38012",allowLocal:true})?(allowLocal:true仅仅开发时才将分片配置到本地,生产时不能这样)-----------------------------------------------如图:配置信息被添加到Config Server的config数据库的shards集合中:【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析??你会发觉,arbiter仲裁节点因为不接收数据,所以直接被mongos在配置阶段就去掉,db.runCommand({addshard:"replset1/127.0.0.1:18010,127.0.0.1:18011,127.0.0.1:18012",allowLocal:true})等价于:db.runCommand({addshard:"replset1/127.0.0.1:18010,127.0.0.1:18011",allowLocal:true})

?

?-----------------------------------------------?//A,配置数据库mydb,启用分片?use admin?db.runCommand({enablesharding:"mydb"})?此时数据库mydb是以分片replset3为基片(primary shard)【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?mydb被配置成启用分片后,配置信息是存放在配置服务器的数据库config的databases集合里!????//B,设置要分片的集合:使集合users以片键_id来分片db.runCommand({shardcollection:"mydb.users",key:{_id:1}})【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析mydb的users集合被配置成启用分片后,配置信息是存放在配置服务器的数据库config的collections集合里!--------------------------------------------?【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?这里可以看到,路由服务器是不会存放配置信息(不用配置dbpath也是这个原因,但会缓存配置服务器上的配置!)?5,Sharding,递增片键方式插入数据?/Apps/mongo/bin/mongo --port 50000??use mydb?测试插入60万条数据for(var i=1; i<=600000; i++) db.users.insert({age:i,name:"jack",addr:"guangzhou",country:"China"})?use admin执行:db.runCommand({enablesharding:"mydb"})使数据库启用分片?db.runCommand({ shardcollection:"mydb.users",key:{_id:1} }) 使集合users以_id为Sharding Key分片?然后等几分钟,集合users的数据就均匀分布到各个分片,分片完成??1,先看看每个trunk,这里测试需要,设置了1MB/trunk,如图?【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析每个trunk记录了片键的范围,还有所在的片?--------------------------------------因为Sharding key 是ObjectId【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析这里ObjectId就像一个递增片键,插入时不能均匀地路由到各片,此时写入的负载很不均匀,集中在一台机器上!?【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析??如图:Balancer正在移动分片的块chunk【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?在递增片键的情况下,数据刚插入完后,数据的分片不均匀,所以数据插入完后,mongos就会用Balancer进行数据的负载均衡!如: Balancer正在执行负载均衡,此时要用到锁,MongoDB 2.2.0 引入了DB级别的锁,不知道分片时是不是也是DB级别的锁呢?这会锁定分片的数据库mydb?图: mongos的Balancer正在执行负载均衡【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析??图: mongos的Balancer正在执行负载均衡【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析??图: mongos的Balancer正在执行负载均衡【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析??图: mongos的Balancer正在执行负载均衡【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?-----------------------------------------过了10+分钟的状态,此时应该分片"均匀"了..【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?细心发觉,怎么"均匀"呢??每个片的chunks是均匀了,每个片的chunks都是33个,【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析因为片replset2是数据库mydb的primary片(上图),又因为此时是递增片,开始时60万条记录全部都插入到这个片中,又因为我们给mongos设置的--chunkSize是1Mb,所以给replset2片均衡数据时,使其每个trunk的size均衡到接近1M就可以了(实际是1.1),??6,Sharding,随机片键方式插入数据?/Apps/mongo/bin/mongo --port 50000??use admin执行:db.runCommand({enablesharding:"mydb"})使数据库启用分片???db.runCommand({ shardcollection:"mydb.user2",key:{shardkey:1} }) 使集合user2以shardkey为Sharding Key分片?【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?空集合user2以shardkey为Sharding Key分片后,就会在配置服务器分配一个(-∞,+∞)的chunks块给数据库mydb的基片replset3,基片很重要,对于一个不分片的集合是存放在基片中的,而对于分片的集合,每一个无限大的chunks块也是分配给基片的!【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析???use mydb?测试插入60万条数据,这里生成的shardkeyfor(var i=1; i<=600000; i++) db.user2.insert({name:"a long name",age:i,addr:"a long address guangzhou",country:"China",?shardkey: Math.random()})??【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析??因为刚开始里,配置服务器里没有chunks块,第一个无限大的块位于基片上,而后来边向数据库插入数据边分裂出更细的chunks块,这时分裂出的块主要分布在基片shard000上所以导致插入操作集中在基片上执行!??现在把集合user2里的数据全部remove掉!那集合就是剩下chunks块的信息(在配置服务器里)?图:集合user2清空后,各片的chunks块数量也不均匀【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?图:没数据,也会对各片进行chunks块数量调整,直至数量平均!?【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?(再次说明:mongos路由负载均衡的本质是:??????????在后台对各片进行负载均衡,直至各片的chunks块数量相等!)?向已有69个chunks块(块分布均匀)的空集合插入30万个随机键的文档for(var i=1; i<=300000; i++) db.user2.insert({name:"a long name",age:i,addr:"a long address guangzhou",country:"China",?shardkey: Math.random()})?【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析?【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析??【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析??【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析??【转】MongoDB Replica Sets + Sharding 草案 及 chunks块 和 片键分析????可见,向已有69个chunks块(块分布均匀)的空集合插入30万个随机键的文档整个插入过程是相当均匀!而块的数量仅仅增加了6块,就是说30万个文档几乎全部"命中"已存在的各个块!?-------------------------------------------------------?8,测试6和7的小结?1:如果刚开始对于新的集合,配置服务器里没有该集合的chunks块信息,这里无论是递增键或随机键,? 数据的插入过程也不会均匀,甚至有可能集中在某台机器上,然后mongos再来执行负载均衡?2: mongos路由会在后台对各片进行负载均衡,直至各片的chunks块数量相等!?3: 对于负载均衡的Sharding Cluster(各片的chunks块数量相等),对于随机键的操作会非常有效,基本整个过程是很均匀的? ? 而此时递增键的操作还是会出现严重的负载不均衡的情况!???--------------------------------------------?5,对现有的表执行Sharding?/Apps/mongo/bin/mongo --port 50000??use mydb?测试插入60万条数据for(var i=1; i<=600000; i++) db.users.insert({age:i,name:"irelandken",addr:"guangzhou",country:"China"})???然后等几分钟,集合users的数据就均匀分布到各个分片,分片完成????--------------------------------------------?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,外部看来是一个数据库??转自?http://blog.csdn.net/irelandken/article/details/8003195

读书人网 >其他数据库

热点推荐