这是《MongoDB 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 本章搭建一个可用于学习和验证的 MongoDB 环境。学习环境可以用 Docker 或单机二进制包,生产环境必须部署副本集,并提前规划认证、磁盘、监控和备份。
2.1 版本选择
建议选择当前仍在维护生命周期内的稳定版本,例如 MongoDB 7.x 或 8.x。不同版本的默认参数、审计能力、聚合算子和分片策略可能有差异。生产升级前应阅读目标版本的兼容性说明和发布说明。
版本确认:
db.version()
db.serverBuildInfo()
2.2 Docker 单节点
docker network create mongo-net
docker run -d \
--name mongo \
--network mongo-net \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=secret123 \
-v mongo-data:/data/db \
mongo:7.0 --bind_ip_all
进入容器:
docker exec -it mongo mongosh -u admin -p secret123
学习环境可以固定 mongo:7.0 这类明确版本。生产环境不建议把密码直接写在命令行参数中,应使用密钥管理或容器编排 Secret。
2.3 二进制安装
以 Linux 为例,安装后先确认数据目录和日志目录:
/var/lib/mongodb
/var/log/mongodb
配置文件通常为 /etc/mongod.conf:
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
net:
port: 27017
bindIp: 127.0.0.1
security:
authorization: enabled
启动与状态:
systemctl start mongod
systemctl status mongod
2.4 mongosh 基础
连接:
mongosh "mongodb://admin:secret123@localhost:27017/admin"
常用命令:
show dbs
use shop
show collections
db.products.findOne()
db.stats()
创建业务数据库和集合:
use shop
db.createCollection("products", {
validator: {
$jsonSchema: {
required: ["sku_id", "title", "price"],
properties: {
sku_id: { bsonType: "string" },
title: { bsonType: "string" },
price: { bsonType: "decimal" }
}
}
}
})
2.5 单节点副本集
很多能力依赖副本集,例如事务、Change Stream 和多数写确认。开发环境可以启动单节点副本集:
docker run -d \
--name mongo-rs \
-p 27017:27017 \
-v mongo-rs-data:/data/db \
mongo:7.0 \
--replSet rs0 \
--bind_ip_all \
--keyFile /etc/mongo-keyfile
初始化:
rs.initiate({
_id: "rs0",
members: [{ _id: 0, host: "localhost:27017" }]
})
查看状态:
rs.status()
db.hello()
2.6 生产部署清单
| 项目 | 建议 |
|---|---|
| 拓扑 | 至少三数据节点副本集,跨故障域部署 |
| 认证 | 启用访问控制和角色最小化 |
| 网络 | 只监听内网,不暴露公网 |
| 存储 | SSD,数据与日志单独监控 |
| 内存 | 工作集尽量放得下 |
| 备份 | 定期快照或 dump,并演练恢复 |
| 监控 | 延迟、复制延迟、连接、慢查询 |
| 副本 | 监控 secondary lag |
| Schema | 应用层契约 + validator |
| 变更 | 低峰执行索引和升级 |
2.7 用户与角色
创建管理员:
use admin
db.createUser({
user: "admin",
pwd: "secret123",
roles: [{ role: "root", db: "admin" }]
})
创建业务用户:
use shop
db.createUser({
user: "shop_app",
pwd: "app-secret",
roles: [
{ role: "readWrite", db: "shop" }
]
})
生产环境应按服务拆分账号,只授予必要数据库权限。
2.8 连接字符串
副本集连接:
mongodb://user:password@mongo1:27017,mongo2:27017,mongo3:27017/shop?replicaSet=rs0&authSource=admin
常用参数:
| 参数 | 说明 |
|---|---|
| replicaSet | 副本集名称 |
| authSource | 认证数据库 |
| readPreference | 读路由策略 |
| w | 写关注 |
| readConcern | 读关注 |
| connectTimeoutMS | 连接超时 |
| serverSelectionTimeoutMS | 选点超时 |
2.9 常见连接问题
| 问题 | 排查 |
|---|---|
| Connection refused | 进程未启动、端口或 bindIp 错误 |
| Authentication failed | 密码、用户库、账号错误 |
| Not primary | 连接 secondary 执行写 |
| Node is not in primary | 副本集状态异常 |
| Timeout | 网络、防火墙、DNS、选点 |
| ReplicaSetNoPrimary | 副本集初始化或选举异常 |
本章小结
学习环境可以用 Docker 或单机 mongod 快速启动;事务、Change Stream 和高可用能力应放在副本集中验证。生产环境从第一天就要考虑认证、网络隔离、副本集拓扑、存储、监控和备份,而不是等上线后再补。
思考题
- 为什么单机 mongod 不适合生产?
- 单节点副本集适合验证哪些能力?
bindIp配置错误会带来什么问题?- 业务账号为什么不应使用 root?
- 连接字符串中
authSource的作用是什么?