部署MongoDB
一、系统设计 (System Design)
知识点 1.1:集群架构拓扑与读写策略语法
核心内容:
- MongoDB 提供三种部署拓扑:单节点(Standalone)、副本集(Replica Set)、分片集群(Sharded Cluster)。
- 副本集通过
rs.*系列命令管理,分片通过sh.*命令管理。 - 读写策略通过连接字符串参数控制:
readPreference、writeConcern。
语法规范:
javascript
// mongosh 语法
rs.initiate(configDoc) // 初始化副本集
rs.add(hostPortOrDoc) // 添加节点
rs.reconfig(newConfigDoc) // 动态重配
sh.enableSharding("dbName") // 启用数据库分片
sh.shardCollection("db.coll", keyDoc, options) // 分片集合
案例代码:初始化3节点副本集
javascript
// mongosh 执行脚本:init_replicaset.js
const rsConfig = {
_id: "rs0", // 副本集名称,全局唯一
members: [
{ _id: 0, host: "mongo1:27017", priority: 2 }, // priority 越高越优先选举为主节点
{ _id: 1, host: "mongo2:27017", priority: 1 },
{ _id: 2, host: "mongo3:27017", priority: 0, hidden: true } // hidden节点不参与读负载与选举
],
settings: {
chainingAllowed: true, // 允许次节点从其他次节点同步(降低主节点网络压力)
heartbeatTimeoutSecs: 10, // 心跳超时时间,超过则标记节点不可用
electionTimeoutMillis: 10000 // 选举超时阈值(默认10s)
}
};
// 在任意一个节点执行初始化
rs.initiate(rsConfig);
// 验证副本集状态
rs.status().members.forEach(m => console.log(`${m.name} -> ${m.stateStr}`));
⚠️ 注意事项:
- 生产环境必须配置奇数投票节点(1/3/5/7),避免脑裂。
priority: 0节点不触发选举,常用于备份或异地容灾节点。- 初始化前确保所有节点时间同步(NTP/Chrony),否则 Kerberos/TLS 握手会失败。
知识点 1.2:WiredTiger 存储引擎与缓存调优语法
核心内容:
- MongoDB 默认使用 WiredTiger 引擎,支持文档级并发控制、数据压缩与检查点机制。
- 缓存大小默认为主机可用内存的 50%(最大 50GB),需根据工作负载手动调整。
语法规范(mongod.conf YAML 结构):
yaml
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true # 开启WAL日志,保障宕机数据不丢失
wiredTiger:
engineConfig:
cacheSizeGB: <float> # 固定缓存大小(GB),覆盖自动计算逻辑
directoryForIndexes: true # 将索引与数据分离存储,优化I/O
collectionConfig:
blockCompressor: snappy # 压缩算法:snappy(默认)/zlib/zstd
案例代码:动态调整缓存与查看引擎状态
javascript
// mongosh 查看当前 WiredTiger 缓存使用率
db.adminCommand({ serverStatus: 1 }).wiredTiger.cache;
// 输出字段解析:
// bytes currently in the cache: 当前缓存占用
// maximum bytes configured: 配置的最大缓存阈值
// 缓存命中率 > 95% 为健康状态,低于 80% 需扩容或优化索引
// 生产推荐:不写死 cacheSizeGB,使用百分比自动分配(MongoDB 7.0+ 支持)
// storage.wiredTiger.engineConfig.cacheSizeGB: 0
// 系统会自动分配 50% 物理内存,且随容器 cgroup 限制动态调整
⚠️ 注意事项:
- 若主机运行多个
mongod实例,必须显式设置cacheSizeGB避免内存竞争。 - 开启
zstd压缩可节省 30%~50% 磁盘,但 CPU 开销增加 10%~15%,适合读多写少场景。
二、虚拟化 (Virtualization)
知识点 2.1:Docker 容器化高可用部署语法
核心内容:
- 使用 Docker Compose 部署副本集需解决:持久化卷、网络隔离、健康检查、节点发现。
- 容器内 MongoDB 必须绑定
0.0.0.0或指定容器网络 IP,关闭bindIp: 127.0.0.1。
语法规范(Docker Compose V2):
yaml
services:
<service_name>:
image: mongo:7.0
volumes:
- ./data:/data/db # 数据持久化
- ./config:/etc/mongod # 配置文件挂载
networks:
- mongo_net
deploy:
resources:
limits:
cpus: '4.0' # 限制CPU核心数
memory: 8G # 限制内存上限
案例代码:3节点副本集 Docker Compose
yaml
# docker-compose.yml
version: "3.9"
services:
mongo1:
image: mongo:7.0
container_name: mongo1
restart: unless-stopped
command: ["--replSet", "rs0", "--config", "/etc/mongod/mongod.conf"]
volumes:
- mongo1_data:/data/db
- ./conf/mongod.conf:/etc/mongod/mongod.conf:ro
networks: [mongo_net]
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 10s
timeout: 5s
retries: 5
mongo2:
<<: *mongo1 # YAML 锚点复用配置
container_name: mongo2
volumes:
- mongo2_data:/data/db
- ./conf/mongod.conf:/etc/mongod/mongod.conf:ro
mongo3:
<<: *mongo1
container_name: mongo3
volumes:
- mongo3_data:/data/db
- ./conf/mongod.conf:/etc/mongod/mongod.conf:ro
volumes:
mongo1_data:
mongo2_data:
mongo3_data:
networks:
mongo_net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24 # 固定子网,便于内部DNS解析或静态IP
⚠️ 注意事项:
- 容器内
mongod.conf必须包含net.bindIp: 0.0.0.0,否则节点间无法通信。 - 首次启动后需进入容器执行
rs.initiate(),或使用初始化脚本挂载至/docker-entrypoint-initdb.d/。
知识点 2.2:虚拟化环境 I/O 调度与 NUMA 绑定
核心内容:
- 虚拟机/云主机默认 I/O 调度器为
mq-deadline,数据库推荐none(NVMe)或bfq(HDD)。 - MongoDB 对 NUMA 敏感,跨 NUMA 节点访问内存会导致延迟抖动,需配置
numactl或systemd绑定。
案例代码:Systemd 服务 NUMA 与 I/O 调度优化
bash
# /etc/systemd/system/mongod.service.d/override.conf
[Service]
# 绑定至 NUMA 节点 0,避免跨节点内存访问延迟
ExecStartPre=/usr/bin/numactl --membind=0 --cpunodebind=0
# 关闭透明大页(THP),WiredTiger 明确要求关闭
ExecStartPre=/usr/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled'
ExecStartPre=/usr/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/defrag'
# I/O 调度器调整(仅对块设备生效,需替换实际设备名)
ExecStartPre=/usr/bin/sh -c 'echo none > /sys/block/vda/queue/scheduler'
LimitNOFILE=64000 # 文件描述符限制
LimitNPROC=64000 # 进程/线程限制
⚠️ 注意事项:
- 云主机通常由 Hypervisor 管理 NUMA,无需手动绑定;物理机/私有云建议保留。
- THP 关闭后 MongoDB 启动日志应无
WARNING: Accessing non-existent database以外的内存警告。
三、配置系统设置 (Configuring System Settings)
知识点 3.1:操作系统内核参数与 Limits 语法
核心内容:
- MongoDB 依赖高并发文件句柄、无交换分区(Swap)、合理 TCP backlog。
- 参数通过
/etc/sysctl.conf与/etc/security/limits.conf持久化。
语法规范:
bash
# sysctl.conf 内核网络参数
net.core.somaxconn = 4096 # TCP 连接队列上限
net.ipv4.tcp_max_syn_backlog = 4096
vm.swappiness = 1 # 尽可能使用物理内存,避免 Swap 抖动
vm.dirty_ratio = 10 # 脏页写回阈值
vm.dirty_background_ratio = 5
# limits.conf 用户资源限制
mongodb soft nofile 64000
mongodb hard nofile 64000
mongodb soft nproc 64000
mongodb hard nproc 64000
案例代码:一键部署脚本片段
bash
#!/bin/bash
# optimize_os.sh
echo "配置内核参数..."
cat <<EOF | sudo tee /etc/sysctl.d/99-mongodb.conf
net.core.somaxconn = 4096
net.ipv4.tcp_max_syn_backlog = 4096
vm.swappiness = 1
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10
EOF
sudo sysctl --system
echo "配置 Limits..."
cat <<EOF | sudo tee /etc/security/limits.d/mongodb.conf
mongodb soft nofile 64000
mongodb hard nofile 64000
mongodb soft nproc 64000
mongodb hard nproc 64000
EOF
echo "禁用 Swap(生产环境强制)..."
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
⚠️ 注意事项:
- MongoDB 7.0+ 启动时会检查 Swap,若启用会输出
WARNING: /proc/sys/vm/swappiness is not set to 0。 nofile必须 ≥ 64000,否则高并发写入时触发Too many open files错误。
知识点 3.2:mongod.conf YAML 完整语法结构
核心内容:
- MongoDB 使用 YAML 格式配置,键值对层级严格缩进(2或4空格,禁止 Tab)。
- 支持环境变量替换:
${ENV_VAR}语法。
案例代码:生产级 mongod.conf
yaml
# mongod.conf
processManagement:
timeZoneInfo: /usr/share/zoneinfo # 时区数据路径
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 16 # 根据物理内存调整
collectionConfig:
blockCompressor: zstd
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true # 日志追加模式,避免轮转丢失
logRotate: reopen # 配合 logrotate 使用
net:
port: 27017
bindIp: 0.0.0.0 # 监听所有网卡
maxIncomingConnections: 2000 # 最大并发连接数
tls:
mode: requireTLS # 强制 TLS 加密
certificateKeyFile: /etc/ssl/mongodb.pem
CAFile: /etc/ssl/ca.pem
replication:
replSetName: rs0 # 副本集名称
oplogSizeMB: 10240 # 10GB oplog,防止慢同步覆盖
security:
authorization: enabled # 开启 RBAC 鉴权
keyFile: /etc/mongodb/keyfile # 节点间通信密钥(权限必须为 600)
⚠️ 注意事项:
keyFile文件权限必须为600,且内容完全一致,否则副本集节点拒绝连接。- YAML 不支持注释符号
#出现在值内部,如path: /var/log/mongod # comment会解析失败。
四、网络配置 (Network Configuration)
知识点 4.1:防火墙策略与 TLS 加密语法
核心内容:
- 生产环境仅开放
27017(或自定义端口)与副本集内部通信端口。 - MongoDB 原生支持 TLS 1.2/1.3,需配置证书链与客户端验证。
案例代码:Firewalld 规则与 MongoDB TLS 连接
bash
# 1. 防火墙策略(CentOS/RHEL)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" port port="27017" protocol="tcp" accept'
sudo firewall-cmd --reload
# 2. 生成自签名证书(仅测试,生产需 CA 签发)
openssl req -x509 -newkey rsa:4096 -keyout mongo.key -out mongo.crt -days 365 -nodes -subj "/CN=mongo"
cat mongo.key mongo.crt > /etc/ssl/mongodb.pem
chmod 600 /etc/ssl/mongodb.pem
javascript
// mongosh TLS 连接语法
const uri = "mongodb://user:pass@mongo1:27017,mongo2:27017,mongo3:27017/admin?replicaSet=rs0&tls=true&tlsCAFile=/etc/ssl/ca.pem&tlsCertificateKeyFile=/etc/ssl/client.pem";
db = connect(uri);
⚠️ 注意事项:
tlsCertificateKeyFile必须包含私钥与证书链,顺序为:私钥 → 服务器证书 → 中间CA → 根CA。- 启用 TLS 后,所有驱动(Java/Node/Python)需配置对应 TLS 参数,否则连接被拒。
知识点 4.2:SRV 连接字符串与 DNS 自动发现
核心内容:
mongodb+srv://协议通过 DNS TXT/SRV 记录自动解析节点列表与连接参数。- 适用于云原生、容器化、动态 IP 环境。
语法规范:
mongodb+srv://[user:pass@]host/dbname?[options]
DNS 记录要求:
_mongodb._tcp.<domain> IN SRV <priority> <weight> <port> <host>
<domain> IN TXT "authSource=admin&replicaSet=rs0&tls=true"
案例代码:DNS 配置与连接示例
bash
# 1. 配置 DNS 记录(Bind9/Cloudflare/Route53 示例)
_mongodb._tcp.example.com. IN SRV 0 5 27017 mongo1.example.com.
_mongodb._tcp.example.com. IN SRV 0 5 27017 mongo2.example.com.
_mongodb._tcp.example.com. IN SRV 0 5 27017 mongo3.example.com.
example.com. IN TXT "authSource=admin&replicaSet=rs0&tls=true"
# 2. 客户端连接(无需列出所有节点)
mongosh "mongodb+srv://admin:secret@example.com/myapp"
⚠️ 注意事项:
- SRV 记录优先级
priority越低越优先,weight控制负载均衡比例。 - 部分企业内网 DNS 不支持 SRV,需切换至标准
mongodb://或部署内部 DNS 服务。
五、系统管理 (System Administration)
知识点 5.1:RBAC 权限模型与用户管理语法
核心内容:
- MongoDB 采用基于角色的访问控制(RBAC),权限分为
数据库级与集群级。 - 内置角色:
read,readWrite,dbAdmin,userAdmin,clusterAdmin,root等。
语法规范:
javascript
db.createUser({
user: "<username>",
pwd: "<password>",
roles: [
{ role: "<roleName>", db: "<database>" },
{ role: "clusterAdmin", db: "admin" }
],
mechanisms: ["SCRAM-SHA-256"], // 认证机制
passwordDigestor: "server" // 密码在服务端哈希
})
案例代码:创建只读应用账号与自定义角色
javascript
use admin
// 1. 创建应用只读账号
db.createUser({
user: "app_reader",
pwd: "Str0ngP@ssw0rd!",
roles: [
{ role: "read", db: "ecommerce" }, // 仅读 ecommerce 库
{ role: "read", db: "analytics" }
]
})
// 2. 创建自定义角色(允许特定集合的更新操作)
db.createRole({
role: "partialUpdater",
privileges: [
{
resource: { db: "inventory", collection: "products" },
actions: ["update", "find"] // 仅允许更新和查询
}
],
roles: [] // 不继承内置角色
})
// 3. 验证权限
db.auth("app_reader", "Str0ngP@ssw0rd!");
db.getCollectionNames(); // 成功
db.products.insertOne({x:1}); // 失败:not authorized
⚠️ 注意事项:
passwordDigestor: "server"为默认值,客户端发送明文密码,服务端哈希存储。- 避免使用
root角色连接业务应用,遵循最小权限原则。
知识点 5.2:自动化备份与监控集成语法
核心内容:
- 逻辑备份:
mongodump/mongorestore(支持 oplog 增量)。 - 物理备份:文件系统快照(LVM/EBS)+
mongod --dbpath离线拷贝。 - 监控指标:通过
/metrics端点暴露 Prometheus 格式数据。
案例代码:增量备份脚本与 Prometheus 配置
bash
#!/bin/bash
# backup.sh
BACKUP_DIR="/opt/mongo_backup/$(date +%Y%m%d_%H%M)"
mkdir -p "$BACKUP_DIR"
# 全量备份 + oplog 截断(支持时间点恢复)
mongodump --uri="mongodb://admin:pass@localhost:27017/admin" \
--oplog \
--out="$BACKUP_DIR" \
--gzip \
--numParallelCollections=4
# 清理7天前备份
find /opt/mongo_backup -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;
echo "Backup completed: $BACKUP_DIR"
yaml
# prometheus.yml 抓取配置
scrape_configs:
- job_name: mongodb
static_configs:
- targets: ["mongo1:9216", "mongo2:9216", "mongo3:9216"]
metrics_path: /metrics
scheme: http
bash
# 启动 MongoDB Exporter(官方推荐)
docker run -d --name mongo_exporter \
-p 9216:9216 \
percona/mongodb_exporter:0.40.0 \
--mongodb.uri="mongodb://exporter_user:pass@localhost:27017/?authSource=admin"
⚠️ 注意事项:
--oplog仅对副本集有效,独立节点无法使用。- Prometheus 抓取间隔建议
15s,配合 Grafana 官方 MongoDB Dashboard(ID: 12735)使用。 - 备份前确保
w: majority写入完成,否则可能丢失未同步数据。
📌 生产部署检查清单(Checklist)
| 阶段 | 必查项 |
|---|---|
| 系统设计 | 奇数投票节点、WiredTiger 缓存比例、oplog 大小 ≥ 10GB |
| 虚拟化 | 容器 CPU/Memory 限制、持久化卷、健康检查就绪 |
| 系统设置 | THP 关闭、nofile≥64000、swappiness=1、numa 绑定 |
| 网络配置 | bindIp 正确、TLS 强制启用、防火墙白名单、SRV 解析验证 |
| 系统管理 | RBAC 权限隔离、自动化备份验证、监控告警阈值配置 |
以上内容可直接用于生产环境部署手册、运维 SOP 或架构评审文档。