前戏
上回说了 MongoDB 的高可用架构有两种, 副本集合分片集群, 这一回我们来探索,分片集群怎么部署吧!
小白: 你好,老花!我想学习如何部署 MongoDB 的分片集群,你能帮帮我吗?
老花: 当然可以!MongoDB 的分片集群(Sharded Cluster)是一种分布式数据库架构,可以帮你处理大量数据和高吞吐量请求。接下来,我会一步步带你完成部署。
docker-compose 部署实战
第一步:准备工作
在我们开始之前,你需要确保已经克隆了这个 GitHub 仓库,并且切换到了with-keyfile-auth
这个文件夹。这个文件夹包含了我们需要的带认证的 docker-compose 配置文件。
git clone https://github.com/minhhungit/mongodb-cluster-docker-compose.git
cd mongodb-cluster-docker-compose/with-keyfile-auth
第二步:创建密钥文件
为了设置认证,我们需要一个密钥文件。我已经帮你创建了一个,但如果你自己想要创建一个,可以按照以下步骤操作:
在 Linux 上,你可以使用以下命令:
openssl rand -base64 756 > mongodb-keyfile
chmod 400 mongodb-keyfile
创建好mongodb-keyfile
后,记得替换文件夹with-keyfile-auth/mongodb-build/auth/
中的文件,然后进行下一步。
第三步:启动所有容器
更新或者安装 docker-compose:
pip install docker-compose -U
现在,我们来启动所有的 Docker 容器。切换到with-keyfile-auth
目录下,然后运行:
docker-compose up -d
Tip: 如果镜像无法拉取, 可以配置一些国内源:
cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://dockerproxy.com",
"https://docker.mirrors.ustc.edu.cn",
"https://docker.nju.edu.cn"
]
}
docker pull docker.m.daocloud.io/mongo:6.0.2
docker tag docker.m.daocloud.io/mongo:6.0.2 mongo:6.0.2
docker-compose up -d
预期的输出如下, 可以看到目前我们已经启动三个分片副本集合,
docker-compose ps
Name Command State Ports
mongo-config-01 docker-entrypoint.sh mongo ... Up 0.0.0.0:27119->27017/tcp,:::27119->27017/tcp
mongo-config-02 docker-entrypoint.sh mongo ... Up 0.0.0.0:27120->27017/tcp,:::27120->27017/tcp
mongo-config-03 docker-entrypoint.sh mongo ... Up 0.0.0.0:27121->27017/tcp,:::27121->27017/tcp
router-01 docker-entrypoint.sh mongo ... Up 0.0.0.0:27117->27017/tcp,:::27117->27017/tcp
router-02 docker-entrypoint.sh mongo ... Up 0.0.0.0:27118->27017/tcp,:::27118->27017/tcp
shard-01-node-a docker-entrypoint.sh mongo ... Up 0.0.0.0:27122->27017/tcp,:::27122->27017/tcp
shard-01-node-b docker-entrypoint.sh mongo ... Up 0.0.0.0:27123->27017/tcp,:::27123->27017/tcp
shard-01-node-c docker-entrypoint.sh mongo ... Up 0.0.0.0:27124->27017/tcp,:::27124->27017/tcp
shard-02-node-a docker-entrypoint.sh mongo ... Up 0.0.0.0:27125->27017/tcp,:::27125->27017/tcp
shard-02-node-b docker-entrypoint.sh mongo ... Up 0.0.0.0:27126->27017/tcp,:::27126->27017/tcp
shard-02-node-c docker-entrypoint.sh mongo ... Up 0.0.0.0:27127->27017/tcp,:::27127->27017/tcp
shard-03-node-a docker-entrypoint.sh mongo ... Up 0.0.0.0:27128->27017/tcp,:::27128->27017/tcp
shard-03-node-b docker-entrypoint.sh mongo ... Up 0.0.0.0:27129->27017/tcp,:::27129->27017/tcp
shard-03-node-c docker-entrypoint.sh mongo ... Up 0.0.0.0:27130->27017/tcp,:::27130->27017/tcp
第四步:初始化副本集
接下来,我们需要初始化配置服务器和分片的副本集。运行以下命令:
docker-compose exec configsvr01 bash "/scripts/init-configserver.js"
docker-compose exec shard01-a bash "/scripts/init-shard01.js"
docker-compose exec shard02-a bash "/scripts/init-shard02.js"
docker-compose exec shard03-a bash "/scripts/init-shard03.js"
第五步:初始化路由器
等待几秒,让配置服务器和分片选举出主节点后,我们就可以初始化路由器了:
docker-compose exec router01 sh -c "mongosh < /scripts/init-router.js"
第六步:设置认证
现在,我们需要设置认证。默认的管理员账户是your_admin
和your_password
,你可以在/scripts/auth.js
文件中修改它们。
#!/bin/bash
mongosh <<EOF
use admin;
db.createUser({user: "admin", pwd: "123456", roles:[{role: "root", db: "admin"}]});
exit;
EOF
运行以下命令来设置认证:
docker-compose exec configsvr01 bash "/scripts/auth.js"
docker-compose exec shard01-a bash "/scripts/auth.js"
docker-compose exec shard02-a bash "/scripts/auth.js"
docker-compose exec shard03-a bash "/scripts/auth.js"
第七步:启用分片并设置分片键
最后,我们需要启用分片并设置分片键。首先,使用以下命令连接到路由器:
docker-compose exec router01 mongosh --port 27017 -u "your_admin" --authenticationDatabase admin
然后,整个初始化就完成了!
接下来,你可以开始向集群中插入数据,使用上一篇博客的脚本来测试分片集群数据了!
这里我们是有 hash 分片来测试:
mongos> use admin
mongos> db.runCommand( { enablesharding : "test" } )
mongos> use test
mongos> db.vast.ensureIndex( { id: 1 } )
mongos> use admin
mongos> db.adminCommand( {shardCollection: "test.vast", key : {id: "hashed"} } )
mongos> use test
mongos> for(i=0;i<20000;i++){ db.vast.insert({"id":i,"name":"woshishuaige","age":i,"date":new Date()}); }
mongos> db.vast.stats()
这里为了比较清晰的显示, 我们可以写一个 js 函数来格式化输出:
mongos> function processStats(stats) {
// 遍历每个shard的统计信息
for (let shardName in stats) {
// 提取每个shard的统计数据
let shardStats = stats[shardName];
// 打印shard名称
print("Shard: " + shardName);
// 提取并打印对象数据和对象占用的大小
print("Objects: " + shardStats.objects);
print("Data Size: " + shardStats.dataSize + " bytes");
print("Average Object Size: " + shardStats.avgObjSize + " bytes");
print("\n");
}
}
mongos> processStats(db.stats().raw);
Shard: rs-shard-02/shard02-a:27017,shard02-b:27017,shard02-c:27017
Objects: 6708
Data Size: 509808 bytes
Average Object Size: 76 bytes
Shard: rs-shard-01/shard01-a:27017,shard01-b:27017,shard01-c:27017
Objects: 6817
Data Size: 518092 bytes
Average Object Size: 76 bytes
Shard: rs-shard-03/shard03-a:27017,shard03-b:27017,shard03-c:27017
Objects: 6475
Data Size: 492100 bytes
Average Object Size: 76 bytes
看起来哈希分片后的数据还是比较均衡的, 你可以比较下这两种分片的运行效率!
测试完毕, 可以使用以下命令进行回收哦~
docker-compose down
后戏
小白: 太棒了,老花!我已经按照你的步骤成功部署了 MongoDB 的分片集群。接下来我该做些什么?
老花: 其实, 这个过程还是挺简单的, 我这里还有一套更简单的部署方式。你知道 Kubernetes
吗? 只需要一个 yaml 文件, 就能部署服务, 并且你可以找下开源的 chart
进行部署! 下一篇, 我们探索快速搭建 k8s
测试环境, 以及怎么在 Kubernetes 上 快速构建分片集群吧! 记得关注哦~