本文最后更新于:2024年11月11日 上午
之前我们介绍过 MongoDB 分片和 GridFS 的工作原理,本文用 Docker 进行实战部署,并在 GridFS 上进行分片测试。
基础准备
实战目标
- Docker compose 配置化部署 MongoDB 服务
- 配置 3 个 config 服务器
- 配置 3 个 分片存储服务器
- 配置 1 个 路由服务器
- 脚本启动、初始化
- 实现 GridFS 数据分片
- 添加 GridFS 数据
- 查看分片效果
环境准备
环境配置
- 安装 Docker
- 安装 mongodbsh
- 配置 docker compose
创建 mongo 网络
检查名为mongo
的网络是否已经存在
1 |
|
如果mongo
网络不存在,需要手动创建:
1 |
|
在 docker compose 文件中添加网络配置
1 |
|
重新启动服务
1 |
|
注意事项
- 如果你正在使用多个Docker Compose文件或者与其他项目共享网络,确保所有项目都使用相同的网络名称。
- 如果你之前已经运行了Docker Compose并且删除了网络,你可能需要先删除旧的容器和卷,然后重新创建网络。
检查时区文件
构建时间同步的多个 MongoDB 服务需要统一的时区信息,通过共用本机的 /etc/localtime
文件实现。
检查该文件是否存在,如果不存在则需要手动创建符号链接,以 Shanghai 时区为例:
1 |
|
更新系统时钟(可选操作)
1 |
|
验证设置
验证时区设置是否正确:
1 |
|
创建文件夹
在根目录创建这样的文件夹结构:
1 |
|
赋予其他用户读写权限
1 |
|
docker-compose 配置
服务定义
在services
部分定义不同的MongoDB容器,包括分片(shard)、配置服务器(config)和路由进程(mongos)。
shard
1 |
|
config
1 |
|
mongos
1 |
|
网络配置
1 |
|
docker-compose.yml 文件
1 |
|
构建容器
用脚本执行,文件 mongo_deploy.sh
1 |
|
执行脚本
1 |
|
GridFS 分片
以 vvd
数据库为例
mongosh 进入 mongos 容器的 mongodb
1 |
|
启用分片,让当前库支持分片
1 |
|
给 fs.chunks
集合分片
可选创建索引
db.fs.chunks.createIndex( { files_id : 1 , n : 1 } )
1 |
|
添加 GridFS 数据
需要进入到 mongos 里,我是这么干的:
1 |
|
之后为了找一个测试文件,我进到 /var/log
中,把 faillog
文件当作测试文件
1
mongofiles -d myDatabase -c myGridFSBucket put /path/to/your/file.txt
这里
-d
指定数据库,-c
指定GridFS存储桶(如果未指定,默认为fs
)。
1 |
|
多执行几遍,权当测试文件
查看分片状态
回到刚刚的 mongosh,这时在 vvd 数据库中查看 collections 可以看到 fs.chunks
和 fs.files
集合,表明 GridFS 数据添加成功:
1 |
|
查看数据:
1 |
|
查看分片状态:
1 |
|
可以看到添加的数据被分配到三个 mongodb 中。
GridFS 分片成功!
用户管理
之后需要手动进行用户管理:
- 连接到 MongoDB
1 |
|
- 创建 root 用户
1 |
|
- 核心数据库管理者,我们的 mongodb 数据库命名为
test_db
1 |
|
- 数据读取者,对
test_db
仅有只读权限:
1 |
|
-
开启访问控制
mongodb 默认关闭访问控制,需要在创建用户后手动开启
1
docker exec -it mongo_mongos bash
在 mongos 容器中执行命令:
1
mongod --auth
迁移
尝试了将本机 /mongodata 文件夹完整移动到服务器,并启动同样配置的分片服务,可以成功迁移数据库。
可能存在其他未知风险。
问题排查
-
如果 容器启动后瞬间 Down 掉,可以通过
docker logs <container_id_or_name>
查看问题原因,我遇到的大多都是磁盘映射的权限问题,听说 777 大法百毒不侵
-
如果 Mongodb 报很多奇怪的错误可以排查是不是版本有问题,6.0 以后mongo 会变成 mongosh
-
MongoDB 删除集合中的数据后不会立刻让出磁盘空间,需要调用:
1
2
3
4# 4.2 版本之前
db.repairDatabase();
# 4.2 版本之后
db.runCommand({ compact: 'yourCollectionName' });如果是分片数据集,则需要进入分片 mongo 中运行命令
删除集合也可以解决问题。
参考资料
- https://jelly.jd.com/article/621370d8263c2201bb85b050
- https://www.mongodb.com/zh-cn/docs/manual/tutorial/add-member-to-shard/
- https://blog.csdn.net/weixin_30239339/article/details/95011903
- https://www.cnblogs.com/realcp1018/p/8652572.html
- https://www.zywvvd.com/notes/coding/dataset/mongodb/MongoDB/
- https://www.zywvvd.com/notes/coding/dataset/mongodb-gridfs/mongodb-gridfs/
- https://www.zywvvd.com/notes/coding/dataset/mongodb-slice/mongodb-slice/
文章链接:
https://www.zywvvd.com/notes/coding/dataset/mongodb-slice-docker/mongodb-slice-docker/
“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”
微信支付
支付宝支付