mongodb介绍
MongoDB 是由 MongoDB Inc. 开发的开源文档型 NoSQL 数据库,以灵活的文档模型、高可扩展性、高性能为核心特性,自 2009 年发布以来,已成为全球最流行的 NoSQL 数据库之一,广泛应用于互联网、金融、电商、物联网等领域。
高可用与高扩展
- 副本集(Replica Set):多节点冗余存储,自动故障切换(主节点宕机后从节点秒级升主),保障数据不丢失、服务不中断;
- 分片集群(Sharding):支持水平扩展,将数据分布到多个节点,突破单节点存储 / 性能瓶颈,适配 TB/PB 级数据;
- 读写分离:读请求可分流到从节点,降低主节点压力。
本手册适配 MongoDB 6.0 LTS (兼容 4.4+/5.0+),基于10.10.11.45/46/47三节点环境,搭建一主两从全数据副本集(无仲裁节点),包含完整部署流程、日常运维、故障处理、性能优化,满足生产级高可用要求.
- 部署核心 :三节点副本集需保证
replSetName和keyFile全节点一致,主节点优先级最高; - 运维重点:监控节点健康、同步延迟、资源使用率,定期备份,权限遵循最小原则;
- 高可用保障:主节点宕机自动切换,从节点同步延迟需及时优化,定期演练故障恢复。
常见问题
- 副本集初始化失败:检查 keyFile 权限 / 网络 / 配置文件;
- 同步延迟高:扩容 OPLOG / 优化硬件 / 降低主节点写入压力;
- 权限不足:确认认证库为 admin,用户具备对应角色。
- 集群架构规划
| 节点 IP | 角色 | 端口 | 核心作用 | 硬件建议(生产) |
|---|---|---|---|---|
| 10.10.11.45 | Primary(主) | 27017 | 处理所有写请求、选举优先级最高 | 8 核 16G/500G SSD(数据盘) |
| 10.10.11.46 | Secondary(从) | 27017 | 同步主节点数据、故障时接替主节点 | 8 核 16G/500G SSD |
| 10.10.11.47 | Secondary(从) | 27017 | 同步主节点数据、分担读请求 | 8 核 16G/500G SSD |
- 前置环境准备(所有节点执行)
-
系统基础配置
1. 关闭防火墙(生产可精准放行27017端口)
systemctl stop firewalld && systemctl disable firewalld
生产环境放行端口(替代关闭防火墙)
firewall-cmd --add-port=27017/tcp --permanent && firewall-cmd --reload
2. 关闭SELinux
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config3. 时间同步(必做,避免副本集选举异常)
yum install -y ntp ntpdate
ntpdate ntp.aliyun.com
systemctl start ntpd && systemctl enable ntpd4. 提升文件句柄限制(解决高并发连接问题)
echo "* soft nofile 65535" >> /etc/security/limits.conf
echo "* hard nofile 65535" >> /etc/security/limits.conf
echo "mongodb soft nproc 65535" >> /etc/security/limits.conf
echo "mongodb hard nproc 65535" >> /etc/security/limits.conf5. 重启系统使配置生效(可选,生产可分批重启)
reboot
-
创建用户和目录
创建mongodb系统用户(无登录权限)
useradd -r -s /sbin/nologin mongodb
创建数据/日志/密钥目录(统一路径)
mkdir -p /data/mongodb/{data,log,key}
chown -R mongodb:mongodb /data/mongodb
chmod 755 /data/mongodb
chmod 700 /data/mongodb/key # 密钥目录严格权限
3.安装 MongoDB(所有节点)
-
添加官方 YUM 源
cat > /etc/yum.repos.d/mongodb-org-6.0.repo << EOF
[mongodb-org-6.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/6.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-6.0.asc
EOF -
安装mongodb并禁止更新
# 安装稳定版
yum install -y mongodb-org
# 禁止自动更新(避免版本漂移)
echo "exclude=mongodb-org*" >> /etc/yum.conf
# 验证安装
mongod --version # 输出6.0.x版本即成功
- 配置文件编写(所有节点
编辑 /etc/mongod.conf(45/46/47 节点仅 bindIp 不同):
# 系统日志配置
systemLog:
destination: file
path: /data/mongodb/log/mongod.log
logAppend: true
logRotate: reopen
verbosity: 0 # 日志级别,生产设0(最低)
# 存储配置
storage:
dbPath: /data/mongodb/data
engine: wiredTiger # 默认高性能引擎
wiredTiger:
engineConfig:
cacheSizeGB: 8 # 按物理内存50%配置(16G内存设8,32G设16)
journalCompressor: snappy # 日志压缩
collectionConfig:
blockCompressor: snappy # 数据压缩
journal:
enabled: true # 必开,崩溃恢复核心
commitIntervalMs: 100 # 日志刷盘间隔
# 网络配置
net:
port: 27017
bindIp: 10.10.11.45 # 45节点填45,46填46,47填47(生产禁止0.0.0.0)
maxIncomingConnections: 2000 # 最大连接数
wireObjectCheck: true # 校验BSON对象完整性
# 副本集核心配置
replication:
replSetName: rs0 # 所有节点必须一致
oplogSizeMB: 40960 # OPLOG大小40G(生产建议磁盘10%)
enableMajorityReadConcern: true # 读一致性保障
# 进程管理
processManagement:
fork: true
pidFilePath: /var/run/mongodb/mongod.pid
timeZoneInfo: /usr/share/zoneinfo # 时区配置
# 安全配置(生产必开)
security:
authorization: enabled # 开启账号密码认证
keyFile: /data/mongodb/key/keyfile # 节点间认证密钥
enableEncryption: false # 如需加密,需配置KMIP
# 监控配置
operationProfiling:
mode: slowOp # 仅记录慢查询
slowOpThresholdMs: 50 # 慢查询阈值(50ms)
rateLimit: 100 # 每秒最多记录100条慢查询
-
生成节点认证密钥(仅 45 节点执行)
生成keyfile(节点间认证,所有节点必须一致)
openssl rand -base64 756 > /data/mongodb/key/keyfile
chmod 600 /data/mongodb/key/keyfile
chown mongodb:mongodb /data/mongodb/key/keyfile同步到46/47节点
scp /data/mongodb/key/keyfile root@10.10.11.46:/data/mongodb/key/
scp /data/mongodb/key/keyfile root@10.10.11.47:/data/mongodb/key/46/47节点修改权限(执行以下命令)
chmod 600 /data/mongodb/key/keyfile && chown mongodb:mongodb /data/mongodb/key/keyfile
-
启动服务(所有节点)
启动mongod
systemctl start mongod
设置开机自启
systemctl enable mongod
验证状态(active (running)为正常)
systemctl status mongod
验证端口监听
ss -tulpn | grep 27017 # 输出10.10.11.xx:27017 LISTEN
4.初始化副本集(仅 45 节点执行)
-
无认证连接主节点
mongo --host 10.10.11.45 --port 27017
-
初始化副本集配置
// 定义副本集配置
var rs_config = {
_id: "rs0",
members: [
{_id: 0, host: "10.10.11.45:27017", priority: 10, votes: 1}, // 主节点(优先级最高)
{_id: 1, host: "10.10.11.46:27017", priority: 1, votes: 1}, // 从节点1
{_id: 2, host: "10.10.11.47:27017", priority: 1, votes: 1} // 从节点2
],
settings: {
chainingAllowed: true, // 允许从节点间同步
heartbeatIntervalMillis: 2000, // 心跳检测间隔(2秒)
electionTimeoutMillis: 10000, // 选举超时(10秒)
catchUpTimeoutMillis: 20000 // 追平数据超时(20秒)
}
};// 初始化副本集(仅执行一次)
rs.initiate(rs_config);// 等待10秒,让节点完成握手
sleep(10000);// 验证副本集状态
rs.status();
执行rs.status()后,需满足:
- 所有节点
health: 1(健康); - 45 节点
stateStr: PRIMARY; - 46/47 节点
stateStr: SECONDARY; syncingTo字段:46/47 指向 45 节点;lagSeconds(同步延迟)< 1 秒。
创建管理员账号(仅 45 节点)
// 切换到admin库
use admin;
// 创建root超级管理员(生产需设置强密码)
db.createUser({
user: "root",
pwd: "MongoDB@Root123!",
roles: [{role: "root", db: "admin"}]
});
// 创建监控用户(最小权限原则)
db.createUser({
user: "monitor",
pwd: "MongoDB@Monitor123!",
roles: [{role: "clusterMonitor", db: "admin"}]
});
// 创建业务用户(示例)
db.createUser({
user: "app_user",
pwd: "MongoDB@app123!",
roles: [{role: "readWriteAnyDatabase", db: "admin"}]
});
// 验证认证
db.auth("root", "MongoDB@Root123!"); // 返回1即成功
// 回收业务用户写权限
use admin;
db.revokeRolesFromUser("app_user", [{role: "readWriteAnyDatabase", db: "admin"}]);
// 授予只读权限
db.grantRolesToUser("app_user", [{role: "readAnyDatabase", db: "admin"}]);
// 查看用户权限
db.getUser("app_user");
- 日常运维操作
核心状态查询(认证后执行)
# 登录集群(推荐用monitor用户)
mongo --host 10.10.11.45 --port 27017 -u monitor -p MongoDB@Monitor123! --authenticationDatabase admin
#登录后操作
// 1. 副本集完整状态
rs.status();
// 2. 简化节点状态输出
rs.status().members.forEach(m => {
print(`节点: ${m.host}, 角色: ${m.stateStr}, 健康: ${m.health}, 延迟: ${m.lagSeconds || 0}s`);
});
// 3. 主从同步详情
rs.printSlaveReplicationInfo();
// 4. 数据库运行状态
db.serverStatus();
// 5. 慢查询(运行超50ms的操作)
db.currentOp({
"secs_running": { "$gt": 0.05 },
"op": { "$nin": ["idle", "getmore"] }
});
// 6. 连接数统计
db.serverStatus().connections; // current(当前)/available(可用)
节点维护操作
// 在当前主节点执行,降级并60秒内不参与选举
rs.stepDown(60);
// 验证新主节点
rs.status().members.forEach(m => {
if (m.stateStr === "PRIMARY") print("新主节点:", m.host);
});
// 添加新从节点(如10.10.11.48)
rs.add("10.10.11.48:27017");
// 移除故障节点(如47节点)
rs.remove("10.10.11.47:27017");
// 修改节点优先级(提升47节点优先级)
var cfg = rs.conf();
cfg.members[2].priority = 5;
rs.reconfig(cfg);
#权限管理
// 回收业务用户写权限
use admin;
db.revokeRolesFromUser("app_user", [{role: "readWriteAnyDatabase", db: "admin"}]);
// 授予只读权限
db.grantRolesToUser("app_user", [{role: "readAnyDatabase", db: "admin"}]);
// 查看用户权限
db.getUser("app_user");
3.全量备份(主节点定时执行)
# 创建备份脚本
cat > /usr/local/bin/mongodb_backup.sh << EOF
#!/bin/bash
BACKUP_DIR="/backup/mongodb/\$(date +%Y%m%d)"
mkdir -p \$BACKUP_DIR
mongodump -u root -p MongoDB@Root123! --authenticationDatabase admin -o \$BACKUP_DIR
# 保留7天备份
find /backup/mongodb -type d -mtime +7 -exec rm -rf {} \;
EOF
# 添加执行权限
chmod +x /usr/local/bin/mongodb_backup.sh
# 添加定时任务(每天凌晨2点)
crontab -e
# 新增一行
0 2 * * * /usr/local/bin/mongodb_backup.sh >> /var/log/mongodb_backup.log 2>&1
数据恢复(目标节点执行)
# 全量恢复
mongorestore -u root -p MongoDB@Root123! --authenticationDatabase admin /backup/mongodb/20260312/
# 恢复指定库
mongorestore -u root -p MongoDB@Root123! --authenticationDatabase admin -d app_db /backup/mongodb/20260312/app_db/
6.日志管理
cat > /etc/logrotate.d/mongod << EOF
/data/mongodb/log/mongod.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 644 mongodb mongodb
postrotate
/bin/kill -SIGUSR1 \$(cat /var/run/mongodb/mongod.pid) > /dev/null 2>&1 || true
endscript
}
EOF
# 手动触发轮转
logrotate -f /etc/logrotate.d/mongod
7.重置管理员密码(忘记密码)
# 1. 45节点停止服务
systemctl stop mongod
# 2. 修改配置文件,注释认证配置
# security:
# authorization: enabled
# keyFile: /data/mongodb/key/keyfile
# 3. 启动服务
systemctl start mongod
# 4. 无认证登录重置密码
mongo --host 10.10.11.45 --port 27017
use admin;
db.changeUserPassword("root", "NewMongoDB@Root123!");
# 5. 恢复配置文件,重启服务
systemctl restart mongod
8.集群中节点异常(剔除异常节点再重新加入)
先确认哪个节点异常(在主节点执行)
mongo --host 10.10.11.45 -u root -p 你的密码 --authenticationDatabase admin
rs.status().members.forEach(m=>{
print(m.host, " 状态:", m.stateStr, " 健康:", m.health)
})
在主节点把坏节点剔除
rs.remove("10.10.11.47:27017");
rs.status() // 应该只剩 45、46
异常节点本身操作:停止服务 + 清空数据
systemctl stop mongod #停止服务
#清空数据
# 备份一下(可选)
mv /data/mongodb/data /data/mongodb/data_bad
mkdir -p /data/mongodb/data
# 权限必须正确
chown -R mongodb:mongodb /data/mongodb
chmod 600 /data/mongodb/key/keyfile
启动节点服务
systemctl start mongod
systemctl status mongod
回到主节点,把它重新加回集群
rs.add("10.10.11.47:27017");