MongoDB分片集群部署:详细生产环境完整搭建

一、生产环境规划与准备

1.1 硬件与资源规划

服务器配置建议(生产环境)
组件 推荐配置 数量 用途说明
Config Server 16GB RAM, 4核CPU, 100GB SSD 3 存储集群元数据
Mongos 8GB RAM, 4核CPU, 50GB SSD 3-6 查询路由
Shard Server 32GB+ RAM, 8核+ CPU, 1TB+ SSD 4-8 存储实际数据
监控服务器 8GB RAM, 4核CPU, 100GB SSD 1 集群监控
网络要求
  • 低延迟网络(<1ms节点间延迟)
  • 1Gbps+ 网络带宽
  • 专用网络分段(隔离MongoDB流量)
  • 内部DNS解析(避免IP变更导致问题)

1.2 系统准备

操作系统优化
bash 复制代码
# 创建MongoDB用户
sudo useradd -r -d /var/lib/mongodb -s /bin/false mongodb

# 设置文件描述符限制
echo "mongodb soft nofile 64000" | sudo tee -a /etc/security/limits.conf
echo "mongodb hard nofile 64000" | sudo tee -a /etc/security/limits.conf
echo "mongodb soft nproc 64000" | sudo tee -a /etc/security/limits.conf
echo "mongodb hard nproc 64000" | sudo tee -a /etc/security/limits.conf

# 设置虚拟内存
echo "vm.swappiness = 1" | sudo tee -a /etc/sysctl.d/99-mongodb.conf
echo "vm.dirty_ratio = 10" | sudo tee -a /etc/sysctl.d/99-mongodb.conf
echo "vm.dirty_background_ratio = 5" | sudo tee -a /etc/sysctl.d/99-mongodb.conf

# 启用配置
sudo sysctl -p /etc/sysctl.d/99-mongodb.conf
目录结构规划
复制代码
/data/
├── configsvr   # Config Server数据目录
├── shard1      # Shard 1数据目录
├── shard2      # Shard 2数据目录
├── ...         # 其他分片
└── mongos      # Mongos日志目录

1.3 安全基础设置

bash 复制代码
# 创建SSL证书(用于内部组件通信)
openssl req -newkey rsa:2048 -new -x509 -days 3650 -nodes \
  -out mongodb-cert.pem -keyout mongodb-key.pem \
  -subj "/C=CN/ST=Beijing/L=Beijing/O=MongoDB/OU=IT Department/CN=mongodb"

# 合并证书和密钥
cat mongodb-cert.pem mongodb-key.pem > mongodb.pem

二、Config Server部署

2.1 安装与配置

bash 复制代码
# 创建Config Server数据目录
sudo mkdir -p /data/configsvr
sudo chown mongodb:mongodb /data/configsvr

# 创建配置文件 /etc/mongod-config.conf
ini 复制代码
# Config Server 配置
sharding:
  clusterRole: configsvr

replication:
  replSetName: configReplSet

security:
  keyFile: /etc/mongodb/keyfile
  clusterAuthMode: keyFile
  sslMode: requireTLS
  sslPEMKeyFile: /etc/mongodb/mongodb.pem

storage:
  dbPath: /data/configsvr
  journal:
    enabled: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 8

net:
  port: 27019
  bindIp: 0.0.0.0
  ssl:
    mode: requireTLS
    PEMKeyFile: /etc/mongodb/mongodb.pem

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

2.2 启动与初始化

bash 复制代码
# 创建密钥文件
openssl rand -base64 756 > /etc/mongodb/keyfile
chmod 600 /etc/mongodb/keyfile
chown mongodb:mongodb /etc/mongodb/keyfile

# 启动Config Server
sudo mongod --config /etc/mongod-config.conf --fork

# 初始化副本集
mongo --port 27019 <<EOF
rs.initiate({
  _id: "configReplSet",
  configsvr: true,
  members: [
    { _id: 0, host: "config1.example.com:27019" },
    { _id: 1, host: "config2.example.com:27019" },
    { _id: 2, host: "config3.example.com:27019" }
  ]
})
EOF

2.3 验证配置

bash 复制代码
mongo --port 27019 <<EOF
rs.status()
db.adminCommand({getCmdLineOpts: 1})
EOF

三、Shard Server部署

3.1 单个Shard配置示例

bash 复制代码
# 创建Shard数据目录
sudo mkdir -p /data/shard1
sudo chown mongodb:mongodb /data/shard1

# 创建配置文件 /etc/mongod-shard1.conf
ini 复制代码
# Shard Server 配置
sharding:
  clusterRole: shardsvr

replication:
  replSetName: shard1ReplSet

security:
  keyFile: /etc/mongodb/keyfile
  clusterAuthMode: keyFile
  sslMode: requireTLS
  sslPEMKeyFile: /etc/mongodb/mongodb.pem

storage:
  dbPath: /data/shard1
  journal:
    enabled: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 16

net:
  port: 27018
  bindIp: 0.0.0.0
  ssl:
    mode: requireTLS
    PEMKeyFile: /etc/mongodb/mongodb.pem

systemLog:
  destination: file
  path: /var/log/mongodb/shard1.log
  logAppend: true
  verbosity: 1

3.2 部署多个Shard

对每个Shard重复以下步骤:
  1. 创建数据目录和配置文件
  2. 启动mongod进程
  3. 初始化副本集
bash 复制代码
# 启动Shard Server
sudo mongod --config /etc/mongod-shard1.conf --fork

# 初始化副本集
mongo --port 27018 <<EOF
rs.initiate({
  _id: "shard1ReplSet",
  members: [
    { _id: 0, host: "shard1-node1.example.com:27018" },
    { _id: 1, host: "shard1-node2.example.com:27018" },
    { _id: 2, host: "shard1-node3.example.com:27018" }
  ]
})
EOF

3.3 验证Shard状态

bash 复制代码
mongo --port 27018 <<EOF
rs.status()
db.adminCommand({getCmdLineOpts: 1})
EOF

四、Mongos部署

4.1 配置文件

bash 复制代码
# 创建日志目录
sudo mkdir -p /var/log/mongodb
sudo chown mongodb:mongodb /var/log/mongodb

# 创建配置文件 /etc/mongos.conf
ini 复制代码
# Mongos 配置
sharding:
  configDB: configReplSet/config1.example.com:27019,config2.example.com:27019,config3.example.com:27019

security:
  keyFile: /etc/mongodb/keyfile
  clusterAuthMode: keyFile
  sslMode: requireTLS
  sslPEMKeyFile: /etc/mongodb/mongodb.pem

net:
  port: 27017
  bindIp: 0.0.0.0
  ssl:
    mode: requireTLS
    PEMKeyFile: /etc/mongodb/mongodb.pem

systemLog:
  destination: file
  path: /var/log/mongodb/mongos.log
  logAppend: true
  verbosity: 1

4.2 启动Mongos

bash 复制代码
# 启动Mongos服务
sudo mongos --config /etc/mongos.conf --fork

# 验证Mongos连接
mongo --port 27017 <<EOF
db.adminCommand({ping: 1})
EOF

五、集群配置与启用分片

5.1 启用分片功能

bash 复制代码
# 添加Shard到集群
mongo --port 27017 <<EOF
sh.addShard("shard1ReplSet/shard1-node1.example.com:27018,shard1-node2.example.com:27018,shard1-node3.example.com:27018")
sh.addShard("shard2ReplSet/shard2-node1.example.com:27018,shard2-node2.example.com:27018,shard2-node3.example.com:27018")
// 添加其他分片...
EOF

5.2 启用数据库和集合分片

javascript 复制代码
// 启用数据库分片
sh.enableSharding("your_database")

// 为集合创建索引(必须在分片前创建)
db.your_collection.createIndex({ "shard_key": 1 })

// 启用集合分片
sh.shardCollection("your_database.your_collection", { "shard_key": 1 })

5.3 配置分片策略

javascript 复制代码
// 设置块大小(默认64MB)
sh.setBalancerState(false)
sh.disableBalancing("your_database.your_collection")
sh.splitAt("your_database.your_collection", { "shard_key": "value" })
sh.moveChunk("your_database.your_collection", { "shard_key": "value" }, "target_shard")
sh.setBalancerState(true)

六、安全配置强化

6.1 创建管理用户

javascript 复制代码
// 在Config Server上创建管理员
mongo --port 27019 <<EOF
use admin
db.createUser({
  user: "clusterAdmin",
  pwd: "StrongPassword123!",
  roles: [
    { role: "root", db: "admin" }
  ]
})
EOF

6.2 创建集群用户

javascript 复制代码
// 在Mongos上创建集群用户
mongo --port 27017 <<EOF
use admin
db.createUser({
  user: "clusterUser",
  pwd: "ClusterPassword456!",
  roles: [
    { role: "clusterAdmin", db: "admin" },
    { role: "readWriteAnyDatabase", db: "admin" }
  ]
})
EOF

6.3 配置防火墙规则

bash 复制代码
# 允许集群内部通信
sudo ufw allow from 192.168.1.0/24 to any port 27017,27018,27019

# 限制客户端访问
sudo ufw allow from 10.10.10.0/24 to any port 27017

# 禁止其他所有访问
sudo ufw deny 27017/tcp
sudo ufw deny 27018/tcp
sudo ufw deny 27019/tcp

6.4 启用SCRAM-SHA-256认证

yaml 复制代码
# 在所有配置文件中添加
security:
  authorization: enabled
  keyFile: /etc/mongodb/keyfile
  clusterAuthMode: keyFile
  sslMode: requireTLS
  sslPEMKeyFile: /etc/mongodb/mongodb.pem

七、监控与备份配置

7.1 Prometheus监控设置

bash 复制代码
# 安装MongoDB exporter
wget https://github.com/percona/mongodb_exporter/releases/download/v0.32.0/mongodb_exporter-0.32.0.linux-amd64.tar.gz
tar xvf mongodb_exporter-0.32.0.linux-amd64.tar.gz
./mongodb_exporter --mongodb.uri="mongodb://clusterUser:ClusterPassword456!@localhost:27017" --discovering-mode
Prometheus配置示例
yaml 复制代码
scrape_configs:
  - job_name: 'mongodb'
    static_configs:
      - targets: ['localhost:9216']

7.2 备份策略

逻辑备份(适合小数据量)
bash 复制代码
# 定期备份脚本
mongodump --host mongos1.example.com --port 27017 \
  --username clusterUser --password ClusterPassword456! \
  --authenticationDatabase admin \
  --gzip --archive=/backup/mongodb_$(date +%Y%m%d).gz
物理备份(适合大数据量)
bash 复制代码
# 停止平衡器
mongo --port 27017 <<EOF
sh.stopBalancer()
EOF

# 停止Mongos
sudo systemctl stop mongos

# 备份Config Server
rsync -avz /data/configsvr /backup/configsvr_$(date +%Y%m%d)

# 备份Shard数据
rsync -avz /data/shard1 /backup/shard1_$(date +%Y%m%d)
# 重复其他Shard...

# 重启Mongos
sudo systemctl start mongos

# 重新启用平衡器
mongo --port 27017 <<EOF
sh.startBalancer()
EOF

八、性能优化与调优

8.1 内核参数优化

bash 复制代码
# 创建优化配置
echo "vm.nr_hugepages = 1280" | sudo tee -a /etc/sysctl.d/99-mongodb.conf
echo "net.core.somaxconn = 1024" | sudo tee -a /etc/sysctl.d/99-mongodb.conf
echo "net.ipv4.tcp_max_syn_backlog = 2048" | sudo tee -a /etc/sysctl.d/99-mongodb.conf

# 应用配置
sudo sysctl -p /etc/sysctl.d/99-mongodb.conf

8.2 WiredTiger引擎优化

yaml 复制代码
# 在Shard配置文件中添加
storage:
  wiredTiger:
    engineConfig:
      cacheSizeGB: 24  # 为80%可用内存
      journalCompressor: zlib
    collectionConfig:
      blockCompressor: zlib

8.3 读写关注配置

javascript 复制代码
// 设置写关注
db.getMongo().setWriteConcern({ w: "majority", wtimeout: 5000 })

// 设置读关注
db.getMongo().setReadPref("nearest")

九、集群验证与测试

9.1 基本状态检查

javascript 复制代码
// 检查集群状态
sh.status()

// 检查分片分布
sh.chunkDistribution("your_database.your_collection")

// 检查连接状态
db.currentOp({ "active": true })

9.2 性能测试

bash 复制代码
# 使用mongo-perf测试
mongo-perf --port 27017 --host mongos1.example.com \
  --username clusterUser --password ClusterPassword456! \
  --authenticationDatabase admin \
  --db test --coll test_coll \
  --docSize 1024 --numDocs 10000 \
  --numInserters 10 --numReaders 10

9.3 故障恢复测试

javascript 复制代码
# 模拟Config Server故障
sudo systemctl stop mongod-config

# 模拟Shard故障
sudo systemctl stop mongod-shard1

# 模拟网络分区
iptables -A OUTPUT -d shard1-node1.example.com -j DROP

# 恢复测试
sudo systemctl start mongod-config
sudo systemctl start mongod-shard1
iptables -D OUTPUT -d shard1-node1.example.com -j DROP

十、生产环境维护指南

10.1 日常维护任务

任务 频率 说明
检查集群状态 每日 sh.status()
检查慢查询 每日 db.currentOp({ "secs_running": { "$gt": 5 } })
备份验证 每周 恢复测试
索引分析 每月 db.collection.explain("executionStats")
容量规划 每月 评估数据增长趋势

10.2 升级策略

逐步升级流程
  1. 升级Config Server(一次一个节点)
  2. 升级Shard Server(一次一个副本集)
  3. 升级Mongos(一次一个实例)
bash 复制代码
# 升级Config Server节点
sudo systemctl stop mongod-config
sudo apt-get install mongodb-org=4.4.10
sudo systemctl start mongod-config

# 验证升级
mongo --port 27019 <<EOF
db.adminCommand({getCmdLineOpts: 1})
EOF

10.3 常见问题处理

数据分布不均
javascript 复制代码
// 查看块分布
sh.chunkDistribution("db.collection")

// 手动分割热点块
sh.splitAt("db.collection", { "shard_key": "hot_value" })

// 迁移块
sh.moveChunk("db.collection", { "shard_key": "hot_value" }, "target_shard")
查询性能下降
javascript 复制代码
// 分析查询计划
db.collection.explain("executionStats").find({ query })

// 添加缺失索引
db.collection.createIndex({ "field": 1 })

十一、最佳实践总结

部署前的 checklist

  • 服务器资源满足生产要求
  • 网络延迟和带宽测试完成
  • 操作系统已优化
  • 安全证书已生成
  • 密钥文件已创建

部署中的 checklist

  • Config Server 3节点副本集已部署
  • 每个Shard是3节点副本集
  • Mongos至少3个实例
  • 分片键已精心选择
  • 安全配置已启用

部署后的 checklist

  • 集群状态验证通过
  • 监控系统已配置
  • 备份策略已实施
  • 性能基准测试完成
  • 故障恢复测试通过

附录:常用管理命令

集群管理

javascript 复制代码
// 添加新分片
sh.addShard("newShardReplSet/newshard-node1:27018,newshard-node2:27018,newshard-node3:27018")

// 暂停平衡器
sh.stopBalancer()

// 恢复平衡器
sh.startBalancer()

// 手动分割块
sh.splitAt("db.collection", { "shard_key": "value" })

// 迁移块
sh.moveChunk("db.collection", { "shard_key": "value" }, "target_shard")

监控命令

javascript 复制代码
// 查看当前操作
db.currentOp({ "active": true })

// 查看慢查询
db.setProfilingLevel(1, 100) // 记录>100ms查询

// 查看块分布
sh.chunkDistribution("db.collection")

故障诊断

javascript 复制代码
// 查看日志
tail -f /var/log/mongodb/*.log

// 检查副本集状态
rs.status()

// 查看集群状态
sh.status()

关键提示 :MongoDB分片集群是为大规模数据设计的解决方案,但也是MongoDB中最复杂的部署模式。切勿在生产环境直接部署,应在测试环境充分验证后再上线。定期审查分片键选择是否仍然适用业务需求,因为分片键一旦选定无法更改。最后,始终确保有可靠的备份和恢复策略,分片集群的数据丢失比单机部署更难恢复。

通过遵循本指南,您将能够部署一个高可用、高性能、安全可靠的MongoDB分片集群,为您的业务提供强大的数据存储和查询能力。记住,部署只是开始,持续的监控、调优和维护才是保持集群健康的关键。

相关推荐
bropro2 小时前
MySQL不使用子查询的原因
android·数据库·mysql
野生技术架构师2 小时前
Java面试精选:数据库 + 数据结构 +JVM+ 网络 +JAVA+ 分布式
java·数据库·面试
枫叶丹2 小时前
复杂SQL性能突围:代价驱动的连接条件下推策略与工程实践
数据库
fengye2071612 小时前
MongoDB 安装与配置
数据库·mongodb
银河麒麟操作系统2 小时前
银河麒麟服务器操作系统IO机制详解
数据库·redis·缓存
OxyTheCrack2 小时前
【C++】一篇文章悲观锁与乐观锁与其思想在C++语言中的应用
linux·开发语言·数据库·c++·笔记
执笔论英雄2 小时前
【cuda】 pinpaged
android·java·数据库
一招定胜负2 小时前
大模型的API调用
数据库
czlczl200209252 小时前
插入时先写DB后写Redis?分布式中传统双写模式的缺陷
数据库·redis·分布式