MongoDB分片介绍(三)——分布式集群部署及维护

我们提到过,MongoDB分片需要三个角色才能完成,一个是Config Server作为元数据存储服务器,一个是Mongos实例作为查询路由转发器,最后是MongoD实例用于存储实际用户数据。

一、启动实例

Config Server其实也是一个MongoDB实例,只不过我们通过启动时增加--configsvr选项将其功能专注于集群元数据的处理,每个Config Server都有一套完整且独立的集群元数据。在实际生产环境下,我们需要部署三个Config Server在不同的机器上,以提高可用性。在测试环境下,我们可以将三个Config Server部署在一台机器上,或者只部署一个Config Server,默认情况下Config Server的端口号为27019

[root@localhost bin]# mkdir -p /mongodb/data/configdb1
[root@localhost bin]# mkdir -p /mongodb/data/configdb2
[root@localhost bin]# mkdir -p /mongodb/data/configdb3

我们给每个Config Server单独设置一个配置文件,每个配置文件的configsvr选项都设置为true。由于在同一台机器上运行,我们将各Config Server的端口号依次为27119、27219、27319,数据库目录依次为configdb1、configdb2、configdb3,其中configsvr1如下:

fork = true
bind_ip = 127.0.0.1
port = 27119
quiet = true
dbpath = /mongodb/data/configdb1
logpath = /mongodb/log/mongod_configdb1.log
logappend = true
journal = true
configsvr=true
smallfiles = true
oplogSize =  128

 

[root@localhost bin]#./mongod --config /mongodb/mongodb.conf1

[root@localhost bin]#./mongod --config /mongodb/mongodb.conf2

[root@localhost bin]#./mongod --config /mongodb/mongodb.conf3

 

完成对Config Server的启动后,我们就可以启动mongos实例。mongos实例是一个轻量级的实例,不需要存储数据的目录,其默认端口号为27017。在启动mongos实例时,我们需要指定ConfigServer的IP和端口号。为了避免因Config Server IP地址变化导致MongoDB实例和Mongos实例重新启动,因此最好给每个Config Server设置一个DNS逻辑名,Mongos实例启动时直接使用Config Server的DNS逻辑名和端口号。我们给mongos实例设置的配置文件如下:


fork = true
bind_ip = 127.0.0.1
port = 27017
quiet = true
configdb= 127.0.0.1:27119,127.0.0.1:27219,127.0.0.1:27319
logpath = /mongodb/log/mongos.log

下面启动mongos实例和sharding实例,sharding实例启动和普通Mongod实例基本相同,只是多设置一个shardsvr为TRUE即可,带上该参数后mongod实例的默认端口号为27018。我们拟启动两个sharding实例,端口号依次为27118、27218。

[root@localhost bin]# ./mongos --config  /mongodb/mongodb.s 

[root@localhost bin]# ./mongod --config  /mongodb/mongodb.sh1

[root@localhost bin]# ./mongod --config  /mongodb/mongodb.sh2

 

二、初始化sharding

1、连接mongos实例,将两个sharding实例增加到集群中

[root@localhost bin]# ./mongo --port 27017
MongoDB shell version: 2.5.2
connecting to: 127.0.0.1:27017/test
mongos> sh.addShard( "127.0.0.1:27118" )sh.addShard( "127.0.0.1:27118" )
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> sh.addShard( "127.0.0.1:27218" )sh.addShard( "127.0.0.1:27218" )
{ "shardAdded" : "shard0001", "ok" : 1 }

2、使能test数据库以支持集群

mongos> sh.enableSharding("test")
{ "ok" : 1 }

 

3、使能people集合以支持分片

mongos> sh.shardCollection("test.people", {user_id:1})
{ "collectionsharded" : "test.people", "ok" : 1 }

 

三、观察集群状态

我们可以使用sh.status()查看集群的状态。下面的命令结果显示,在集群中有两个分片,两个数据库中只有Test数据库支持分片,其主分片是shard0000。主分片是指在分片开始之前,集合数据所在的位置。

mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "version" : 3,
        "minCompatibleVersion" : 3,
        "currentVersion" : 4,
        "clusterId" : ObjectId("5284bb99c8b3dd65fd2c3ea6")
}
  shards:
        {  "_id" : "shard0000",  "host" : "127.0.0.1:27118" }
        {  "_id" : "shard0001",  "host" : "127.0.0.1:27218" }
  databases:
        {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
        {  "_id" : "test",  "partitioned" : true,  "primary" : "shard0000" }
                test.people
                        shard key: { "user_id" : 1 }
                        chunks:
                                shard0000       1
                        { "user_id" : { "$minKey" : 1 } } -->> { "user_id" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 0)

mongos>

 

由于people表中还没有数据,上面集群状态显示people集合只有一个Chunk。下面我们插入1万数据,观察一下Chunk分裂的过程。

use test

people = ["Marc", "Bill", "George", "Eliot", "Matt", "Trey", "Tracy", "Greg", "Steve", "Kristina"]

 for(var i=0; i<10000; i++){
 name = people[Math.floor(Math.random()*people.length)];
 user_id = i;
 boolean = [true, false][Math.floor(Math.random()*2)];
 added_at = new Date();
 number = Math.floor(Math.random()*10001);
 db.people.save({"name":name, "user_id":user_id, "boolean":boolean,"added_at":added_at,"number":number });
}

在数据完成插入以后,我们再执行sh.status(),发现目前已经people集合拥有三个Chunk,shard0000拥有2个chunk,shard0001拥有1一个chunk。shard0000上,user_id从最小值到0为一个chunk,0到5739为另外一个chunk;shard0001,user_id从5739到最大值为一个chunk。

.............................. 

test.people
                        shard key: { "user_id" : 1 }
                        chunks:
                                shard0000       2
                                shard0001       1
                        { "user_id" : { "$minKey" : 1 } } -->> { "user_id" : 0 } on : shard0000 Timestamp(2, 1)
                        { "user_id" : 0 } -->> { "user_id" : 5739 } on : shard0000 Timestamp(1, 3)
                        { "user_id" : 5739 } -->> { "user_id" : { "$maxKey" : 1 } } on : shard0001 Timestamp(2, 0)

 我们继续向people集合插入数据,user_id从1万到100万,合计99万条记录。在插入完成后发现chunk分裂成了8个,shard0000和shard0001上各4个Chunk。

..................................  

              test.people
                        shard key: { "user_id" : 1 }
                        chunks:
                                shard0001       4
                                shard0000       4
                        { "user_id" : { "$minKey" : 1 } } -->> { "user_id" : 0 } on : shard0001 Timestamp(8, 0)
                        { "user_id" : 0 } -->> { "user_id" : 5739 } on : shard0000 Timestamp(8, 1)
                        { "user_id" : 5739 } -->> { "user_id" : 188952 } on : shard0001 Timestamp(7, 1)
                        { "user_id" : 188952 } -->> { "user_id" : 372157 } on : shard0000 Timestamp(4, 2)
                        { "user_id" : 372157 } -->> { "user_id" : 555370 } on : shard0001 Timestamp(5, 2)
                        { "user_id" : 555370 } -->> { "user_id" : 746356 } on : shard0001 Timestamp(6, 2)
                        { "user_id" : 746356 } -->> { "user_id" : 929568 } on : shard0000 Timestamp(7, 2)
                        { "user_id" : 929568 } -->> { "user_id" : { "$maxKey" : 1 } } on : shard0000 Timestamp(7, 3)

四、集群维护

1、迁移Config Server

一般集群拥有三个Config Server,当某一台出现故障时,我们可以进行在线迁移。在迁移过程中,如果不需要更改Config Server的主机名称,则步骤如下:

  • 使用sh.setBalancerState(false)暂时停止后台的Balance活动,并使用sh.getBalancerState()确认
  • 关闭拟迁移的Config Server,此时集群的配置数据变得只读,所有Chunk的分裂和平衡活动都被禁止,但是用户正常的数据插入是被允许的。
  • 更改DNS解析条目,将原主机名称指向新的IP地址。
  • 将老Config Server的DB目录复制到新Config Server的DB目录下。
  • 在新机器上启动Config Server实例,并使用sh.setBalancerState(true)启动Chunk平衡。

如果涉及到的Config Server的主机名称发生变化,则需要一定的停机重启时间,步骤如下:

  • 使用sh.setBalancerState(false)暂时停止后台的Balance活动,并使用sh.getBalancerState()确认
  • 关闭拟迁移的Config Server,此时集群的配置数据变得只读,所有Chunk的分裂和平衡活动都被禁止,但是用户正常的数据插入是被允许的。
  • 将老Config Server的DB目录复制到新Config Server的DB目录下。
  • 在新机器上启动Config Server实例。
  • 关闭现有的实例,包括Config Server实例,mongos实例和存放实际用户数据的集群实例
  • 启动所有集群实例
  • 更新mongos实例的configdb配置参数,并重新启动mongos实例
  • 使用sh.setBalancerState(true)启动Chunk平衡

从上述过程可以看出,如果需要更改configdb的配置需要对整个集群进行停机,因此我们在规划时应尽可能采用DNS方式解析Config Server以提高集群的可用性。

 

2. 维护集群实例

需要将增加新集群实例到集群中时,我们需要首先启动拟新增加的集群实例,然后在mongo shell环境下执行sh.addShard()命令即可。

当我们需要从集群中删除一个集群实例时,一般步骤如下:

  • 使用sh.setBalancerState(TRUE)启动Chunk平衡
  • 找到准备删除的shard名字,例如我们拟删除mongodb0分片
  • 执行命令removeShard,此命令将从该分片中移出所有Chunk到其他分片,如使用db.runCommand( { removeShard: "mongodb0" } )删除mongodb0分片。
  • 使用removeShard不断观察迁移的进展情况,直到返回"remove shard completed successfully"消息。
  • 使用sh.status()命令查看是否有文档是以该分片为主分片的,movePrimary命令迁移主分片,如db.runCommand( { movePrimary: "products", to: "mongodb1" })将products文档的主分片设置为mongodb1.

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值