一、生产环境规划与准备
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重复以下步骤:
- 创建数据目录和配置文件
- 启动mongod进程
- 初始化副本集
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 升级策略
逐步升级流程
- 升级Config Server(一次一个节点)
- 升级Shard Server(一次一个副本集)
- 升级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分片集群,为您的业务提供强大的数据存储和查询能力。记住,部署只是开始,持续的监控、调优和维护才是保持集群健康的关键。