本文最后更新于:2025年2月14日 下午
之前我们介绍过 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 |
|
command 解释
1 |
|
此命令用于启动一个 MongoDB 实例,并为其配置多个关键参数,具体含义如下:
1. --shardsvr
- 作用:指定该实例作为 分片集群中的一个分片节点。
- 默认端口:
27018
(普通mongod
默认端口为27017
)。 - 分片集群角色:
- 分片节点负责存储实际数据,并将数据分布到集群中。
- 需与其他分片、配置服务器(
config servers
)和路由服务器(mongos
)协同工作。
2. --directoryperdb
- 作用:启用 每个数据库独立存储目录。
- 文件管理:
- 默认情况下,所有数据库文件存储在统一的
data/db
目录中。 - 启用后,每个数据库会有自己的子目录(如
data/db/db1
、data/db/db2
),便于管理和维护。
- 默认情况下,所有数据库文件存储在统一的
3. --replSet shard1
- 作用:将该分片节点配置为 副本集
shard1
的成员。 - 副本集的意义:
- 每个分片通常是一个副本集,以提高数据可用性和容错性。
- 副本集需包含多个节点(至少 3 个推荐),通过选举机制实现自动故障转移。
- 初始化步骤:
- 需在启动后执行
rs.initiate()
和rs.add()
初始化副本集,添加其他成员。
- 需在启动后执行
4. --wiredTigerCacheSizeGB 2
- 作用:设置 WiredTiger 存储引擎的缓存大小为 2GB。
- 缓存机制:
- WiredTiger 是 MongoDB 默认存储引擎,缓存用于加速数据和索引的访问。
- 建议值为系统内存的 50% 以下(例如 64GB 内存可设为 30GB)。
- 优化意义:避免占用过多内存影响其他服务,此处限制为 2GB。
5. --auth
- 作用:启用 访问控制,强制要求客户端连接时进行身份验证。
- 安全要求:
- 需先创建管理员用户(如
admin
),再为应用程序创建普通用户。 - 用户需分配角色(如
readWrite
、dbAdmin
)以限制权限。
- 需先创建管理员用户(如
网络配置
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://github.com/docker-library/mongo/issues/475
-
生成
replica.key
1 |
|
- 构建带有该 key 的容器
1 |
|
- 构建镜像:
1 |
|
- docker-compose.yml
1 |
|
可以建立不崩溃的容器,但是没有成功创建默认用户。
参考资料
- 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://github.com/docker-library/mongo/issues/475
文章链接:
https://www.zywvvd.com/notes/coding/dataset/mongodb-slice-docker/mongodb-slice-docker/
“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”

微信支付

支付宝支付