将副本集转换为分片群集
在本页面
Overview
本教程将单个三成员副本集转换为具有两个分片的分片集群。每个分片都是一个独立的三元副本集。本教程特定于 MongoDB 3.6. 对于其他版本的 MongoDB,请参阅相应版本的《 MongoDB 手册》。
步骤如下:
-
创建初始的三成员副本集并将数据插入到集合中。参见设置初始副本集。
-
启动配置服务器和mongos。参见部署配置服务器副本集和 mongos。
-
将初始副本集添加为分片。参见将初始副本集添加为分片。
-
创建第二个分片并添加到集群。参见添加第二个碎片。
-
分割所需的集合。参见分片集合。
Prerequisites
本教程总共使用十台服务器:一台服务器用于mongos,三台服务器分别用于第replica set,第二个副本集和配置服务器副本集。
每个服务器在系统内必须具有可解析的域,主机名或 IP 地址。
本教程使用默认数据目录(例如/data/db
和/data/configdb
)。创建具有适当权限的适当目录。要使用其他路径,请参见配置文件选项。
Procedures
设置初始副本集
此过程将创建初始的三成员副本集rs0
。副本集成员位于以下主机上:mongodb0.example.net
,mongodb1.example.net
和mongodb2.example.net
。
使用适当的选项启动副本集的每个成员。
对于每个成员,使用以下设置启动mongod实例:
- 将replication.replSetName选项设置为副本集名称,
如果您的应用程序连接到多个副本集,则每个副本集应具有不同的名称。某些驱动程序通过副本集名称对副本集连接进行分组。
-
将net.bindIp选项设置为 IP 或以逗号分隔的 IP 列表,然后
-
根据您的部署设置任何其他设置。
在本教程中,三个mongod实例与以下主机关联:
副本集成员 | Hostname |
---|---|
Member 0 | mongodb0.example.net |
Member 1 | mongodb1.example.net |
Member 2 | mongodb2.example.net |
以下示例通过--replSet和--bind_ip命令行选项指定副本集名称和 ip 绑定:
Warning
绑定到非 localhost(例如可公开访问)的 IP 地址之前,请确保已保护群集免受未经授权的访问。有关安全建议的完整列表,请参见Security Checklist。至少考虑enabling authentication和加强网络基础设施。
mongod --replSet "rs0" --bind_ip localhost,<ip address of the mongod host>
对于<ip address>
,请指定mongod实例的 IP 地址或主机名,远程 Client 端(包括副本集的其他成员)可以使用该 IP 地址或主机名连接到该实例。
另外,您也可以在configuration file中指定副本集名称和ip addresses:
replication:
replSetName: "rs0"
net:
bindIp: localhost,<ip address>
要以配置文件开始mongod,请使用--config选项指定配置文件的路径:
mongod --config <path-to-config>
在生产部署中,您可以配置init script来 Management 此过程。初始化脚本超出了本文档的范围。
将 mongo shell 连接到其中一个 mongod 实例。
从运行mongod的同一台计算机(在本教程中为mongodb0.example.net
)中,启动mongo Shell。要连接mongod并在27017
的默认端口上监听 localhost,只需发出:
mongo
根据您的路径,您可能需要指定mongo二进制文件的路径。
启动副本集。
在mongo shell 中,对副本集成员 0 运行rs.initiate()。
Important
在副本集的仅一个且仅一个 mongod实例上运行rs.initiate()。
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
中,并且可能需要几分钟的时间,具体取决于您的系统。
要确定主要对象,请使用rs.status()。
在副本集的主数据库上发出以下操作:
use test
var 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();
有关部署副本集的更多信息,请参见部署副本集。
重新启动副本集为分片
在版本 3.4 中进行了更改:对于 MongoDB 3.4 分片群集,必须通过配置文件设置sharding.clusterRole或通过命令行选项--shardsvr,将**的分片mongod实例显式指定为shardsvr
。
确定主要和次要成员。
将mongo shell 连接到其中一个成员,然后运行rs.status()确定主要成员和次要成员。
使用--shardsvr 选项重新启动辅助成员。
一次备份一个,使用--shardsvr选项重新启动每个secondary。要 continue 使用同一端口,请包含--port选项。根据您的部署,包括其他选项,例如--bind_ip。
Warning
绑定到非 localhost(例如可公开访问)的 IP 地址之前,请确保已保护群集免受未经授权的访问。有关安全建议的完整列表,请参见Security Checklist。至少考虑enabling authentication和加强网络基础设施。
mongod --replSet "rs0" --shardsvr --port 27017 --bind_ip localhost,<ip address of the mongod host>
包括适用于您的部署的任何其他选项。对其他辅助服务器重复此步骤。
降级初级。
将mongo shell 连接到主节点,然后降级主节点。
rs.stepDown()
使用--shardsvr 选项重新启动主数据库。
使用--shardsvr选项重新启动主数据库。要 continue 使用同一端口,请包含--port选项。
mongod --replSet "rs0" --shardsvr --port 27017 --bind_ip localhost,<ip address of the mongod host>
包括适用于您的部署的任何其他选项。
部署配置服务器副本集和 mongos
此过程为config servers和mongos部署三人副本集。
-
配置服务器使用以下主机:
mongodb7.example.net
,mongodb8.example.net
和mongodb9.example.net
。 -
mongos使用
mongodb6.example.net
。
将配置服务器部署为三成员副本集。
在mongodb7.example.net
,mongodb8.example.net
和mongodb9.example.net
上启动配置服务器。指定相同的副本集名称。配置服务器使用默认数据目录/data/configdb
和默认端口27019
。
Warning
绑定到非 localhost(例如可公开访问)的 IP 地址之前,请确保已保护群集免受未经授权的访问。有关安全建议的完整列表,请参见Security Checklist。至少考虑enabling authentication和加强网络基础设施。
mongod --configsvr --replSet configReplSet --bind_ip localhost,<ip address of the mongod host>
要修改默认设置或包括特定于您的部署的其他选项,请参阅mongod或配置文件选项。
将mongo shell 连接到其中一台配置服务器,然后运行rs.initiate()以启动副本集。
Important
在副本集的仅一个且仅一个 mongod实例上运行rs.initiate()。
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
上,启动mongos,指定配置服务器副本集名称,后跟斜杠/
以及配置服务器主机名和端口中的至少一个。
mongos --configdb configReplSet/mongodb07.example.net:27019,mongodb08.example.net:27019,mongodb09.example.net:27019 --bind_ip localhost,<ip address of the mongos host>
将初始副本集添加为分片
以下过程将初始副本集rs0
添加为分片。
将 mongoShell 连接到 mongos。
mongo mongodb6.example.net:27017/admin
添加分片。
使用sh.addShard方法将分片添加到集群中:
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
。
在版本 3.4 中进行了更改:对于 MongoDB 3.4 分片群集,必须通过配置文件设置sharding.clusterRole或通过命令行选项--shardsvr,将**的分片mongod实例显式指定为shardsvr
。
使用适当的选项启动副本集的每个成员。
对于每个成员,启动mongod,通过replSet
选项指定副本集名称,并通过--shardsvr选项将其用作分片。根据需要指定其他选项,例如--bind_ip。
Warning
绑定到非 localhost(例如可公开访问)的 IP 地址之前,请确保已保护群集免受未经授权的访问。有关安全建议的完整列表,请参见Security Checklist。至少考虑enabling authentication和加强网络基础设施。
有关特定于复制的参数,请参见Replication Options。
mongod --replSet "rs1" --shardsvr --port 27017 --bind_ip localhost,<ip address of the mongod host>
对rs1
副本集的其他两个成员重复此步骤。
将 mongo shell 连接到副本集成员。
将mongo shell 连接到副本集的一个成员(例如mongodb3.example.net
)
mongo mongodb3.example.net
启动副本集。
在mongo shell 中,运行rs.initiate()以启动一个包含当前成员的副本集。
Important
在副本集的仅一个且仅一个 mongod实例上运行rs.initiate()。
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" }
]
})
将 mongoShell 连接到 mongos。
mongo mongodb6.example.net:27017/admin
添加分片。
在连接到mongos的mongo shell 中,使用sh.addShard()方法将分片添加到集群中:
sh.addShard( "rs1/mongodb3.example.net:27017,mongodb4.example.net:27017,mongodb5.example.net:27017" )
分片集合
将 mongoShell 连接到 mongos。
mongo mongodb6.example.net:27017/admin
启用数据库分片。
在分片集合之前,必须首先为集合的数据库启用分片。对数据库启用分片不会重新分配数据,但可以在该数据库中分片集合。
以下操作启用对test
数据库的分片:
sh.enableSharding( "test" )
该操作返回操作状态:
{ "ok" : 1 }
确定分片键。
为了使集合成为碎片,请确定碎片密钥。 shard key确定 MongoDB 如何在分片之间分发文档。好的分片键:
-
具有在所有文档中平均分配的值,
-
将经常同时访问的文档分组为连续的块,并且
-
允许在碎片之间有效分配活动。
使用指定的分片键对集合进行分片后,您将无法更改分片键。有关分片键的更多信息,请参见Shard Keys。
此过程将使用number
字段作为test_collection
的分片键。
在分片键上创建索引。
在分片非空集合之前,请创建一个分片索引。
use test
db.test_collection.createIndex( { number : 1 } )
分片集合。
在test
数据库中,对test_collection
进行分片,将number
指定为分片键。
use test
sh.shardCollection( "test.test_collection", { "number" : 1 } )
该方法返回操作状态:
{ "collectionsharded" : "test.test_collection", "ok" : 1 }
确认分片处于平衡状态。
要确认平衡活动,请在test
数据库中运行db.stats()或db.printShardingStatus()。
use test
db.stats()
db.printShardingStatus()
db.stats()的示例输出:
{
"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
}
db.printShardingStatus()的示例输出:
--- 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" : 1
autosplit:
Currently enabled: yes
balancer:
Currently enabled: yes
Currently running: yes
Collections with active migrations:
test.test_collection started at Mon Nov 05 2018 15:16:45 GMT-0500
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
1 : Success
databases:
{ "_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)
再次运行这些命令,以证明chunks正在从rs0
迁移到rs1
。