Skip to content

MongoDB 集群安装指南

复制集安装

MongoDB 复制集由多个 MongoDB 实例组成,提供高可用性和数据冗余,包含一个主节点(Primary)和多个从节点(Secondary),支持自动故障转移,适合需要高可用性的应用。

1. 环境准备

硬件要求

组件要求
服务器数量至少 3 台(1 主 2 从)
CPU至少 4 核
内存至少 8GB
存储至少 100GB SSD
网络高速、低延迟的局域网

软件要求

  • MongoDB 相同版本(建议使用 LTS 版本)
  • 操作系统:Linux(Ubuntu/CentOS/RHEL)或 Windows Server
  • 关闭 SELinux 和防火墙(或配置相应规则)

服务器规划

主机名IP 地址角色端口
mongo1192.168.1.101主节点27017
mongo2192.168.1.102从节点27017
mongo3192.168.1.103从节点27017

2. 安装 MongoDB

在所有节点上安装 MongoDB,参考 MongoDB Linux 安装指南

3. 配置复制集

创建数据目录

bash
# 在所有节点上执行
sudo mkdir -p /data/mongo
sudo chown -R mongod:mongod /data/mongo

修改配置文件

编辑 /etc/mongod.conf,在所有节点上添加以下配置:

yaml
# 基本配置
storage:
  dbPath: /data/mongo
  journal:
    enabled: true

systemLog:
  destination: file
  path: /var/log/mongodb/mongod.log
  logAppend: true

net:
  port: 27017
  bindIp: 0.0.0.0

replication:
  replSetName: rs0  # 复制集名称

启动 MongoDB 服务

bash
# 在所有节点上执行
sudo systemctl start mongod
sudo systemctl enable mongod

4. 初始化复制集

在任意一个节点上连接到 MongoDB,并初始化复制集:

javascript
// 连接到 MongoDB
mongosh

// 初始化复制集
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "192.168.1.101:27017" },
    { _id: 1, host: "192.168.1.102:27017" },
    { _id: 2, host: "192.168.1.103:27017" }
  ]
})

5. 验证复制集状态

javascript
// 查看复制集状态
rs.status()

// 查看复制集配置
rs.conf()

// 查看从节点复制信息
rs.printSlaveReplicationInfo()

6. 添加仲裁者(可选)

如果只有 2 个数据节点,可以添加一个仲裁者(Arbiter)来满足多数派要求:

javascript
// 添加仲裁者
rs.addArb("192.168.1.104:27017")

分片集群安装

MongoDB 分片集群由多个复制集组成,提供水平扩展能力,包含分片(Shard)、配置服务器(Config Server)和路由服务器(mongos),支持数据分片和负载均衡,适合需要处理大量数据和高并发请求的应用。

1. 环境准备

服务器规划

组件主机名IP 地址端口数量
配置服务器config1192.168.1.201270193
config2192.168.1.20227019
config3192.168.1.20327019
路由服务器mongos1192.168.1.301270172
mongos2192.168.1.30227017
分片 1shard1_1192.168.1.401270183
shard1_2192.168.1.40227018
shard1_3192.168.1.40327018
分片 2shard2_1192.168.1.501270183
shard2_2192.168.1.50227018
shard2_3192.168.1.50327018

2. 安装 MongoDB

在所有节点上安装 MongoDB,参考 MongoDB Linux 安装指南

3. 配置服务器安装

创建数据目录

bash
# 在所有配置服务器上执行
sudo mkdir -p /data/configdb
sudo chown -R mongod:mongod /data/configdb

修改配置文件

编辑 /etc/mongod.conf,在所有配置服务器上添加以下配置:

yaml
# 基本配置
storage:
  dbPath: /data/configdb
  journal:
    enabled: true

systemLog:
  destination: file
  path: /var/log/mongodb/config.log
  logAppend: true

net:
  port: 27019
  bindIp: 0.0.0.0

replication:
  replSetName: configReplSet  # 配置服务器复制集名称

sharding:
  clusterRole: configsvr  # 配置服务器角色

启动配置服务器

bash
# 在所有配置服务器上执行
sudo systemctl start mongod
sudo systemctl enable mongod

初始化配置服务器复制集

在任意一个配置服务器上连接到 MongoDB,并初始化复制集:

javascript
// 连接到配置服务器
mongosh --port 27019

// 初始化配置服务器复制集
rs.initiate({
  _id: "configReplSet",
  configsvr: true,
  members: [
    { _id: 0, host: "192.168.1.201:27019" },
    { _id: 1, host: "192.168.1.202:27019" },
    { _id: 2, host: "192.168.1.203:27019" }
  ]
})

4. 分片安装

创建数据目录

bash
# 在所有分片节点上执行
sudo mkdir -p /data/shard
sudo chown -R mongod:mongod /data/shard

修改配置文件

编辑 /etc/mongod.conf,在所有分片节点上添加以下配置:

yaml
# 基本配置
storage:
  dbPath: /data/shard
  journal:
    enabled: true

systemLog:
  destination: file
  path: /var/log/mongodb/shard.log
  logAppend: true

net:
  port: 27018
  bindIp: 0.0.0.0

replication:
  replSetName: shard1  # 分片 1 复制集名称
  # replSetName: shard2  # 分片 2 复制集名称(在分片 2 节点上使用)

sharding:
  clusterRole: shardsvr  # 分片角色

启动分片节点

bash
# 在所有分片节点上执行
sudo systemctl start mongod
sudo systemctl enable mongod

初始化分片复制集

在每个分片的任意一个节点上连接到 MongoDB,并初始化复制集:

javascript
// 连接到分片 1 节点
mongosh --port 27018

// 初始化分片 1 复制集
rs.initiate({
  _id: "shard1",
  members: [
    { _id: 0, host: "192.168.1.401:27018" },
    { _id: 1, host: "192.168.1.402:27018" },
    { _id: 2, host: "192.168.1.403:27018" }
  ]
})
javascript
// 连接到分片 2 节点
mongosh --port 27018

// 初始化分片 2 复制集
rs.initiate({
  _id: "shard2",
  members: [
    { _id: 0, host: "192.168.1.501:27018" },
    { _id: 1, host: "192.168.1.502:27018" },
    { _id: 2, host: "192.168.1.503:27018" }
  ]
})

5. 路由服务器安装

创建日志目录

bash
# 在所有路由服务器上执行
sudo mkdir -p /var/log/mongodb
sudo chown -R mongod:mongod /var/log/mongodb

启动路由服务器

bash
# 在所有路由服务器上执行
mongos --configdb configReplSet/192.168.1.201:27019,192.168.1.202:27019,192.168.1.203:27019 --bind_ip 0.0.0.0 --port 27017 --logpath /var/log/mongodb/mongos.log --logappend --fork

创建系统服务(可选)

创建 /etc/systemd/system/mongos.service 文件:

ini
[Unit]
Description=MongoDB Sharded Cluster Router
After=network.target

[Service]
User=mongod
Group=mongod
ExecStart=/usr/bin/mongos --configdb configReplSet/192.168.1.201:27019,192.168.1.202:27019,192.168.1.203:27019 --bind_ip 0.0.0.0 --port 27017 --logpath /var/log/mongodb/mongos.log --logappend
PIDFile=/var/run/mongodb/mongos.pid
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=always

[Install]
WantedBy=multi-user.target

启动并启用服务:

bash
sudo systemctl start mongos
sudo systemctl enable mongos

6. 配置分片集群

连接到任意一个路由服务器,并配置分片集群:

javascript
// 连接到路由服务器
mongosh

// 添加分片
db.adminCommand({ addShard: "shard1/192.168.1.401:27018,192.168.1.402:27018,192.168.1.403:27018" })
db.adminCommand({ addShard: "shard2/192.168.1.501:27018,192.168.1.502:27018,192.168.1.503:27018" })

// 查看分片状态
db.adminCommand({ listShards: 1 })

// 启用数据库分片
db.adminCommand({ enableSharding: "test" })

// 对集合进行分片(按 _id 字段的哈希值分片)
db.adminCommand({ shardCollection: "test.collection", key: { _id: "hashed" } })

// 或按范围分片
db.adminCommand({ shardCollection: "test.collection", key: { created_at: 1 } })

集群安全配置

1. 启用认证

创建管理员用户

javascript
// 连接到主节点或 mongos
use admin

// 创建根管理员用户
db.createUser({
  user: "admin",
  pwd: "password",
  roles: [{ role: "root", db: "admin" }]
})

修改配置文件

在所有节点的配置文件中添加:

yaml
security:
  authorization: enabled
  keyFile: /etc/mongodb/keyfile

创建密钥文件

bash
# 在任意一个节点上创建密钥文件
oopenssl rand -base64 756 > /etc/mongodb/keyfile
chmod 400 /etc/mongodb/keyfile
chown mongod:mongod /etc/mongodb/keyfile

# 将密钥文件复制到所有节点
scp /etc/mongodb/keyfile 192.168.1.102:/etc/mongodb/
scp /etc/mongodb/keyfile 192.168.1.103:/etc/mongodb/
# 复制到其他所有节点...

重启服务

bash
# 在所有节点上重启服务
sudo systemctl restart mongod
# 重启 mongos
sudo systemctl restart mongos

2. 配置 TLS/SSL

参考 MongoDB SSL/TLS 配置

集群监控

1. 内置监控

javascript
// 查看集群状态
db.adminCommand({ replSetGetStatus: 1 })  // 复制集状态
db.adminCommand({ listShards: 1 })        // 分片状态
db.adminCommand({ shardConnString: 1 })   // 分片连接信息

2. 监控工具

  • MongoDB Atlas:内置监控和告警
  • Prometheus + Grafana:使用 MongoDB Exporter 收集指标
  • Datadog:自动发现和监控 MongoDB 集群
  • MongoDB Ops Manager:企业级监控和管理

集群维护

1. 备份与恢复

2. 升级

  • 参考 MongoDB 升级流程
  • 复制集升级:滚动升级,先升级从节点,再升级主节点
  • 分片集群升级:先升级配置服务器,再升级分片,最后升级 mongos

3. 扩容

复制集扩容

javascript
// 添加新节点
rs.add("192.168.1.104:27017")

// 查看节点状态
rs.status()

分片集群扩容

javascript
// 添加新分片
db.adminCommand({ addShard: "shard3/192.168.1.601:27018,192.168.1.602:27018,192.168.1.603:27018" })

// 平衡分片数据
db.adminCommand({ balancerStart: 1 })

常见问题及解决方案

1. 复制集初始化失败

原因

  • 网络连接问题
  • 防火墙配置问题
  • 配置文件错误
  • 时钟不同步

解决方案

  • 检查网络连接和防火墙设置
  • 验证配置文件语法
  • 同步所有节点的系统时钟
  • 查看日志文件获取详细错误信息

2. 分片集群无法添加分片

原因

  • 分片复制集未正确初始化
  • 网络连接问题
  • 认证配置错误

解决方案

  • 验证分片复制集状态
  • 检查网络连接和防火墙设置
  • 验证认证配置和密钥文件
  • 查看 mongos 日志获取详细错误信息

3. 集群状态异常

原因

  • 节点故障
  • 网络分区
  • 资源不足

解决方案

  • 检查节点状态和日志
  • 修复故障节点
  • 恢复网络连接
  • 增加节点资源

最佳实践

1. 规划与设计

  • 根据业务需求选择合适的集群类型
  • 合理规划服务器数量和配置
  • 考虑未来扩容需求
  • 设计合适的分片键

2. 部署

  • 使用相同版本的 MongoDB
  • 配置适当的硬件资源
  • 启用认证和 TLS/SSL
  • 配置监控和告警

3. 操作与维护

  • 定期备份数据
  • 监控集群状态和性能
  • 定期进行故障演练
  • 及时升级 MongoDB 版本
  • 记录所有操作和变更

4. 性能优化

  • 为查询创建合适的索引
  • 优化分片键设计
  • 调整 WiredTiger 缓存大小
  • 监控慢查询并优化

常见问题(FAQ)

Q1: 复制集最少需要多少个节点?

A1: 复制集最少需要 3 个节点(1 主 2 从)来实现自动故障转移。如果只有 2 个数据节点,可以添加一个仲裁者(Arbiter)来满足多数派要求。

Q2: 分片集群最少需要多少个服务器?

A2: 分片集群的最小配置:

  • 配置服务器:3 个
  • 路由服务器:2 个
  • 分片:至少 1 个分片,每个分片 3 个节点
  • 总共至少 8 个服务器

Q3: 如何选择分片键?

A3: 选择分片键的原则:

  • 高选择性:具有大量不同值
  • 均匀分布:数据能均匀分布到各个分片
  • 查询模式匹配:与查询模式匹配,减少跨分片查询
  • 避免热点:避免写入热点

Q4: 如何监控集群性能?

A4: 监控集群性能的方法:

  • 使用 MongoDB 内置命令(rs.status(), db.serverStatus())
  • 使用 MongoDB Atlas 或其他监控工具
  • 监控关键指标:CPU、内存、磁盘 I/O、网络、复制延迟等
  • 设置合理的告警阈值

Q5: 如何处理集群故障?

A5: 处理集群故障的步骤:

  1. 识别故障类型和影响范围
  2. 查看日志获取详细错误信息
  3. 根据故障类型采取相应的修复措施
  4. 验证故障已解决
  5. 分析故障原因,防止再次发生

Q6: 如何升级集群?

A6: 升级集群的步骤:

  1. 备份数据
  2. 查看 MongoDB 升级文档,了解版本间的兼容性
  3. 按照正确的顺序升级(复制集:从节点 -> 主节点;分片集群:配置服务器 -> 分片 -> mongos)
  4. 验证升级后的集群状态
  5. 测试应用连接和功能

Q7: 如何扩容集群?

A7: 扩容集群的方法:

  • 复制集:添加新节点
  • 分片集群:添加新分片或扩展现有分片的节点
  • 垂直扩容:增加节点的硬件资源
  • 水平扩容:增加节点数量

Q8: 如何保障集群安全?

A8: 保障集群安全的措施:

  • 启用认证和授权
  • 配置 TLS/SSL 加密
  • 限制网络访问(防火墙、bindIp)
  • 定期更新 MongoDB 版本,修复安全漏洞
  • 定期进行安全审计

Q9: 如何优化集群性能?

A9: 优化集群性能的方法:

  • 为查询创建合适的索引
  • 优化分片键设计
  • 调整 WiredTiger 缓存大小
  • 优化查询语句
  • 增加节点资源
  • 考虑读写分离

Q10: 如何选择合适的集群类型?

A10: 选择集群类型的依据:

  • 复制集:适合需要高可用性和数据冗余的应用
  • 分片集群:适合需要处理大量数据和高并发请求的应用
  • 考虑数据量、并发量、可用性要求和预算等因素

集群部署案例

案例 1:小型应用复制集部署

需求

  • 高可用性
  • 数据量较小(< 1TB)
  • 并发请求较少

部署方案

  • 3 个节点的复制集
  • 每个节点:4 核 CPU,8GB 内存,100GB SSD
  • 启用认证和 TLS/SSL
  • 配置监控和告警

案例 2:大型应用分片集群部署

需求

  • 数据量大(> 10TB)
  • 高并发请求
  • 水平扩展能力

部署方案

  • 2 个分片,每个分片 3 个节点
  • 3 个配置服务器
  • 2 个路由服务器
  • 每个节点:8 核 CPU,16GB 内存,500GB SSD
  • 启用认证和 TLS/SSL
  • 配置详细的监控和告警
  • 设计合适的分片键