概述
本教程将单个三成员副本集转换为包含两个切片的切片集群。 每个切片都是一个独立的三成员副本集。 本教程是特定于MongoDB 4.0测试的。 大概流程如下:
- 创建初始的三成员副本集并往集合中插入数据。
- 启动配置服务器和。
- 将初始副本集添加为切片。
- 创建第二个切片并添加到集群中。
- 分割想进行切分的集合。
先决条件
本教程总共使用了10台服务器:一台运行 ,三台运行第一个,三台运行第二个副本集,三台运行。(如果资源有限,也可能进行资源复用,缩小到三台,注意修改对应的服务端口。)
每个服务器必须在系统中有一个可解析的域、主机名或IP地址。
本教程使用默认的数据目录( /data/db
和 /data/configdb
) 。创建具有适当权限的适当目录。 参考 可以适当好修改配置。
步骤
建立初始副本集
此步骤创建初始的三成员副本集rs0。 复本集成员运行于以下主机: mongodb0.example.net
, mongodb1.example.net
, 和 mongodb2.example.net
。
-
使用适当的选项启动复本集的每个成员。
对于每个成员,使用以下设置启动mongod实例:
- 使用 来设置副本集名称。 如果你的应用程序连接到多个副本集,每个副本集应该有一个不同的名称。 一些驱动程序是根据副本集名称对副本集连接进行分组的。
- 将选项设置为hostname/ip或以逗号分隔的主机名/ip列表
- 根据部署的需要设置任何其他配置。
三个mongod实例分配如下:
Replica Set Member Hostname Member 0 mongodb0.example.net
Member 1 mongodb1.example.net
Member 2 mongodb2.example.net
启动命令如下
mongod --replSet "rs0" --bind_ip localhost,
配置文件的格式如下:
replication: replSetName: "rs0"net: bindIp: localhost,
使用配置文件启动的命令如下:
mongod --config
- 用shell连接到其中一个mongod实例。
- 启动复制集在mongo终端里运行rs.initiate()命令来启动配置集,只需在一台mongod实例上运行即可。具体内容如下:
rs.initiate( { _id : "rs0", members: [ { _id: 0, host: "mongodb0.example.net:27017" }, { _id: 1, host: "mongodb1.example.net:27017" }, { _id: 2, host: "mongodb2.example.net:27017" } ]})
以上命令执行后, MongoDB会使用默认的复本集配置启动一个复本集。
- 创建一个新集合并插入数据下面的步骤将向
test_collection
集合添加100万条数据,这可能需要几分钟的时间。可以使用 rs.status()命令来查看是否位于primary节点上。在副本集的primary节点上运行如下命令:use testvar bulk = db.test_collection.initializeUnorderedBulkOp();people = ["Marc", "Bill", "George", "Eliot", "Matt", "Trey", "Tracy", "Greg", "Steve", "Kristina", "Katie", "Jeff"];for(var i=0; i<1000000; i++){ user_id = i; name = people[Math.floor(Math.random()*people.length)]; number = Math.floor(Math.random()*10001); bulk.insert( { "user_id":user_id, "name":name, "number":number });}bulk.execute();
部署副本集的更多说明请查看
以切片的形式重新启动复本集
从 MongoDB 3.4开始,切片集群的mongod实例必须明确地将其角色指定为 shardsvr
,可以通过配置文件的 选项和命令行的 来设置。
备注:带有 shardsvr
角色的 默认使用 27018
端口。可以通过 配置或 参数来修改默认端口。
- 查看主(primary)从(secondary)成员用 shell连接到其中一台mongod中,运行 命令可以查看主从信息。
- 用
--shardsvr
参数重新启动从节点每次操作一个从节点,使用 参数重新启动从节点的mongod服务。 其它配置根据需要设置。具体命令如下:mongod --replSet "rs0" --shardsvr --port 27017 --bind_ip localhost,
- 给从节点添加切片角色后,给主节点添加切片角色前需要将主节点的primary角色stepDown掉用 shell连接到primary,执行stepdown命令来降职主节点,如下:
rs.stepDown()
- 用
--shardsvr
参数重启primary服务(此时primary已经就成了secondary)命令如下所示,具体配置根据需要设置:mongod --replSet "rs0" --shardsvr --port 27017 --bind_ip localhost,
部署配置服务器副本集和mongos
步骤会部署三个成员的 副本集和。
- 配置服务器运行在:
mongodb7.example.net
,mongodb8.example.net
和mongodb9.example.net
.。 - 运行在
mongodb6.example.net
- 将配置服务器部署为三个成员的副本集配置服务器使用的默认目录为
/data/configdb
,默认端口为27019
,具体命令如下所示:mongod --configsvr --replSet configReplSet --bind_ip localhost,
用 shell连接到其中一台配置服务器运行 来初始化副本集群。具体命令内容如下所示:
rs.initiate( { _id: "configReplSet", configsvr: true, members: [ { _id: 0, host: "mongodb07.example.net:27019" }, { _id: 1, host: "mongodb08.example.net:27019" }, { _id: 2, host: "mongodb09.example.net:27019" } ]} )
- 启动mongos实例在
mongodb6.example.net
,启动 服务时要指定配置服务器的副本集名称,/
后面至少带有一个配置服务器的hostname和端口。命令如下所示:mongos --configdb configReplSet/mongodb07.example.net:27019,mongodb08.example.net:27019,mongodb09.example.net:27019 --bind_ip localhost,
将初始副本集添加为切片
下面的步骤将初始副本集rs0添加为切片。
- 用mongo shell连接到mongos
mongo mongodb6.example.net:27017
- 添加切片使用 方法向集群添加一个切片,命令如下所示:
sh.addShard( "rs0/mongodb0.example.net:27017,mongodb1.example.net:27017,mongodb2.example.net:27017" )
添加第二个切片
下面的步骤会部署一个新的副本集rs1作为第二个切片,并将其添加到集群中。 复本集成员运行在: mongodb3.example.net
, mongodb4.example.net
, 和 mongodb5.example.net
。
- 使用适当的选项启动复本集的每个成员具体配置根据需要设置。具体命令如下:
mongod --replSet "rs1" --shardsvr --port 27017 --bind_ip localhost,
复本集群的成员记得都设置为
rs1
- 用命令连接到shell终端连接 shell到其中一个节点上,命令如下所示:
mongo mongodb3.example.net
- 启动复本集在刚才连接的mongo shell终端运行 命令来启动复本集。具体命令如下所示:
rs.initiate( { _id : "rs1", members: [ { _id: 0, host: "mongodb3.example.net:27017" }, { _id: 1, host: "mongodb4.example.net:27017" }, { _id: 2, host: "mongodb5.example.net:27017" } ]})
- 用mongo shell连接到mongos
mongo mongodb6.example.net:27017/admin
- 添加切片
sh.addShard( "rs1/mongodb3.example.net:27017,mongodb4.example.net:27017,mongodb5.example.net:27017" )
切分collection
- 用mongo shell连接到mongos
mongo mongodb6.example.net:27017/admin
在对集合进行切分之前,必须先启用数据库的切片功能。 启动数据库切片功能并不会重新分布数据,只是让数据库的集合能够被切分。
如下命令所示,启用test数据库切片:
sh.enableSharding( "test" )
会根据 来操作 命令。
操作成功会看到如下信息
{ "ok" : 1 }
- 确定切片键对于要分割的集合,先确定切片键。 切片键决定MongoDB如何在切片之间分布数据。 好的切片键有如下特点:
- 具有均匀地分布在所有数据中的值
- 将经常同时访问的数据分组为连续的块
- 允许在切片之间有效地分配活动
使用指定的切片键对集合进行切分后,就不能更改切片键。有关切片键更多信息查看:
此教程中使用
number
字段作为test_collection
集合的切片键。 - 为切片键创建索引在对非空集合进行切分之前, 必须为切片键创建索引。命令如下所示:
use testdb.test_collection.createIndex( { number : 1 } )
- 切分集合在test数据库中,对
test_collection
进行切分,指定number
作为切片键。命令如下所示:use testsh.shardCollection( "test.test_collection", { "number" : 1 } )
会根据 的 的设置来处理 命令及 方法的写问题。命令操作完成后会看到如下类似的结果:
{ "collectionsharded" : "test.test_collection", "ok" : 1 }
平衡器在下次运行时重新分布数据块。 当客户端向这个集合插入新的数据时, 会将数据路由到适当的切片上。
- 确认切片正在平衡要确认平衡是活跃的,在
test
数据库中运行 或 。use testdb.stats()db.printShardingStatus()
的示例输出 :
{ "raw" : { "rs0/mongodb0.example.net:27017,mongodb1.example.net:27017,mongodb2.example.net:27017" : { "db" : "test", "collections" : 1, "views" : 0, "objects" : 640545, "avgObjSize" : 70.83200339949052, "dataSize" : 45370913, "storageSize" : 50438144, "numExtents" : 0, "indexes" : 2, "indexSize" : 24502272, "ok" : 1, "$gleStats" : { "lastOpTime" : Timestamp(0, 0), "electionId" : ObjectId("7fffffff0000000000000003") } }, "rs1/mongodb3.example.net:27017,mongodb4.example.net:27017,mongodb5.example.net:27017" : { "db" : "test", "collections" : 1, "views" : 0, "objects" : 359455, "avgObjSize" : 70.83259935179647, "dataSize" : 25461132, "storageSize" : 8630272, "numExtents" : 0, "indexes" : 2, "indexSize" : 8151040, "ok" : 1, "$gleStats" : { "lastOpTime" : Timestamp(0, 0), "electionId" : ObjectId("7fffffff0000000000000001") } } }, "objects" : 1000000, "avgObjSize" : 70, "dataSize" : 70832045, "storageSize" : 59068416, "numExtents" : 0, "indexes" : 4, "indexSize" : 32653312, "fileSize" : 0, "extentFreeList" : { "num" : 0, "totalSize" : 0 }, "ok" : 1}
的示例输出 :
--- Sharding Status ---sharding version: { "_id" : 1, "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("5be0a488039b1964a7208c60")}shards: { "_id" : "rs0", "host" : "rs0/mongodb0.example.net:27017,mongodb1.example.net:27017,mongodb2.example.net:27017", "state" : 1 } { "_id" : "rs1", "host" : "rs1/mongodb3.example.net:27017,mongodb4.example.net:27017,mongodb5.example.net:27017", "state" : 1 }active mongoses: "3.6.8" : 1autosplit: Currently enabled: yesbalancer: Currently enabled: yes Currently running: yes Collections with active migrations: test.test_collection started at Mon Nov 05 2018 15:16:45 GMT-0500Failed balancer rounds in last 5 attempts: 0Migration Results for the last 24 hours: 1 : Successdatabases: { "_id" : "test", "primary" : "rs0", "partitioned" : true } test.test_collection shard key: { "number" : 1 } unique: false balancing: true chunks: rs0 5 rs1 1 { "number" : { "$minKey" : 1 } } -->> { "number" : 1195 } on : rs1 Timestamp(2, 0) { "number" : 1195 } -->> { "number" : 2394 } on : rs0 Timestamp(2, 1) { "number" : 2394 } -->> { "number" : 3596 } on : rs0 Timestamp(1, 5) { "number" : 3596 } -->> { "number" : 4797 } on : rs0 Timestamp(1, 6) { "number" : 4797 } -->> { "number" : 9588 } on : rs0 Timestamp(1, 1) { "number" : 9588 } -->> { "number" : { "$maxKey" : 1 } } on : rs0 Timestamp(1, 2)
再次运行这些命令,可以看到块正在从rs0迁移到rs1。