MongoDB入门学习教程,从入门到精通,部署MongoDB(24)

部署MongoDB


一、系统设计 (System Design)

知识点 1.1:集群架构拓扑与读写策略语法

核心内容

  • MongoDB 提供三种部署拓扑:单节点(Standalone)、副本集(Replica Set)、分片集群(Sharded Cluster)。
  • 副本集通过 rs.* 系列命令管理,分片通过 sh.* 命令管理。
  • 读写策略通过连接字符串参数控制:readPreferencewriteConcern

语法规范

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 节点访问内存会导致延迟抖动,需配置 numactlsystemd 绑定。

案例代码: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 或架构评审文档。

相关推荐
2401_865439632 小时前
如何管理Oracle服务器的内核共享内存_shmmax与shmall计算
jvm·数据库·python
专注VB编程开发20年2 小时前
2000条25列数据导出到Sqlite只用40毫秒,ACCESS用时800-1300毫秒
数据库·sqlite·access
m0_716765232 小时前
数据结构--循环链表、双向链表的插入、删除、查找详解
开发语言·数据结构·c++·学习·链表·青少年编程·visual studio
2301_814809862 小时前
HTML函数能否用外接显卡坞提升性能_eGPU对HTML函数帮助【汇总】
jvm·数据库·python
DaqunChen2 小时前
如何优化SQL注入检测性能_通过预编译缓存提升效率
jvm·数据库·python
Greyson12 小时前
如何通过Vagrant快速建库_自动化虚拟机Oracle部署方案
jvm·数据库·python
Wyz201210242 小时前
HTML函数运行时触控屏失灵是硬件故障吗_输入层兼容性测试【详解】
jvm·数据库·python
Greyson12 小时前
TensorFlow中如何冻结模型层_设置layer.trainable等于False实现微调
jvm·数据库·python
老纪的技术唠嗑局2 小时前
4.15 bubseek —— 让 Agent 的足迹,变成团队的洞察
大数据·数据库·sql·游戏·ai·oceanbase·sql优化