MongoDB sharded cluster组成:
shard: 每个shard都需要部署为副本集,负责存储数据,可以部署多个shard
mongos: 相当于路由
config servers:整个集群的配置服务器,也要是副本集
开发环境可以简单一点:
docker 搭建简易分片集群
一个mongos节点、两个shard (每个副本集有两个节点,一个节点也可以)、一个配置服务器(副本集只有一个节点)
创建网络
为整个集群创建一个网络,方便节点之间互通
docker network create mongo_shard_net
启动配置服务器
docker run --name rs_config --network mongo_shard_net \
-d mongo mongod --configsvr --replSet rs_config_server \
--bind_ip_all
连接到配置数据库,执行rs.initiate,配置副本集,注意端口号是27019
docker exec -it rs_config mongosh --port 27019
这里注意configsvr属性为true
rs.initiate(
{
_id : "rs_config_server",
configsvr: true,
members: [
{ _id : 0, host : "rs_config:27019" }
]
}
);
创建shard
启动一个shard, 副本集名称是rs_shard_g1 ,包含两个节点
docker run --name rs_shard_11 --network mongo_shard_net \
-d mongo mongod --shardsvr --replSet rs_shard_g1 \
--bind_ip_all
docker run --name rs_shard_12 --network mongo_shard_net \
-d mongo mongod --shardsvr --replSet rs_shard_g1 \
--bind_ip_all
连接到其中任意一个节点,执行配置
docker exec -it rs_shard_11 mongosh --port 27018
rs.initiate(
{
_id : "rs_shard_g1",
members: [
{ _id : 0, host : "rs_shard_11:27018" },
{ _id : 1, host : "rs_shard_12:27018" }
]
}
);
启动第二个shard,副本集名称rs_shard_g2
docker run --name rs_shard_21 --network mongo_shard_net \
-d mongo mongod --shardsvr --replSet rs_shard_g2 \
--bind_ip_all
docker run --name rs_shard_22 --network mongo_shard_net \
-d mongo mongod --shardsvr --replSet rs_shard_g2 \
--bind_ip_all
docker exec -it rs_shard_21 mongosh --port 27018
配置第二个副本集
rs.initiate(
{
_id : "rs_shard_g2",
members: [
{ _id : 0, host : "rs_shard_21:27018" },
{ _id : 1, host : "rs_shard_22:27018" }
]
}
);
启动mongos
启动mongos, 需要指定配置数据库的副本集
docker run --name shard_mongos --network mongo_shard_net \
-d mongo mongos --configdb rs_config_server/rs_config:27019 \
--bind_ip_all
通过mongosh连接上mongos节点,添加shard
docker exec -it shard_mongos mongosh --port 27017
sh.addShard( "rs_shard_g1/rs_shard_11:27018,rs_shard_12:27018");
sh.addShard( "rs_shard_g2/rs_shard_21:27018,rs_shard_22:27018");
对指定的数据库启用sharding,并指定需要分片的collection
sh.enableSharding("somedb");
sh.shardCollection("somedb.helloDoc", { "name" : "hashed" } )
验证分片效果
连接至mongos,切换到somedb并插入1000条数据
[direct: mongos] test> use somedb
switched to db somedb
[direct: mongos] somedb> for(var i = 0; i < 1000; i++) db.helloDoc.insert({age:i, name:"ly"+i})
{
acknowledged: true,
insertedIds: { '0': ObjectId("6198bd3eea75ef2ba111591a") }
}
分别连接到两个shard,可以看到分别存有部分数据
rs_shard_g1 [direct: primary] somedb> db.helloDoc.count()
508
rs_shard_g2 [direct: primary] somedb> db.helloDoc.count()
492
rs_shard_g2 [direct: primary] somedb>
注意
- 本地测试shard的副本集也可以只有一个,而且默认副本集的从节点是不能直接连接读取数据的,需要
- 宿主机器要用访问数据库的话,至少应该将mongos配置端口映射;配置节点的默认端口是27019,shard节点的默认端口是27018,mongos还是默认27017
-p 27017:27017
- 根据需要,也可以挂载本地文件夹放置数据库文件
-v /my/own/datadir:/data/db
- mongo镜像更多用法,可以参考dockerhub官方文档