环境信息

项目 主节点 从节点
IP 192.168.1.2 192.168.1.3
端口 27017 27017
数据目录 /data/mongo /data/mongo
配置文件 /etc/mongod.conf /etc/mongod.conf
副本集名称 rs0 rs0

第一步:两台机器都做前置检查

192.168.1.2192.168.1.3 上都执行以下操作:

确认数据目录权限

# 确保数据目录存在且归属 mongod 用户
mkdir -p /data/mongo
chown -R mongod:mongod /data/mongo
chmod 755 /data/mongo

开放防火墙端口

firewall-cmd --permanent --add-port=27017/tcp
firewall-cmd --reload

确认 SELinux 状态

# 如果是 enforcing,需要放行或临时关闭
getenforce

# 如果输出 Enforcing,执行:
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

# 或者
# 给 /data/mongo 打上 mongod 需要的安全上下文
semanage fcontext -a -t mongod_var_lib_t "/data/mongo(/.*)?"
# 应用上下文
restorecon -Rv /data/mongo

添加时间同步

yum install -y chrony
systemctl enable chronyd --now
chronyc -a makestep
chronyc sources -v

第二步:修改两台机器的 mongod.conf

编辑 /etc/mongod.conf,确保以下关键配置项正确。两台机器配置完全一致

# 存储配置
storage:
  dbPath: /data/mongo
  journal:
    enabled: true

# 日志配置
systemLog:
  destination: file
  path: /var/log/mongodb/mongod.log
  logAppend: true

# 网络配置 —— 关键!必须绑定本机 IP
net:
  port: 27017
  bindIp: 0.0.0.0

# 副本集配置 —— 两台机器名称必须相同
replication:
  replSetName: rs0
  oplogSizeMB: 2048

重点说明:

  • bindIp: 0.0.0.0:必须允许外部连接,否则两台机器无法互相通信。生产环境建议改为 bindIp: 192.168.1.2(主)/ 192.168.1.3(从),仅绑定内网 IP。
  • replSetName: rs0:两台机器的副本集名称必须完全一致。
  • oplogSizeMB:可根据业务量调整,默认一般是数据目录所在磁盘的 5%。

第三步:重启两台机器的 MongoDB 服务

# 两台机器都执行
systemctl restart mongod
systemctl status mongod

确认状态为 active (running),并检查日志无报错:

tail -50 /var/log/mongodb/mongod.log

如果看到类似 Replication consistency check passedwaiting for connections 的日志,说明启动正常。


第四步:初始化副本集(仅在主节点执行)

连接到 192.168.1.2 的 MongoDB:

mongosh --host 192.168.1.2 --port 27017

如果 mongosh 未安装,可用旧版 mongo 命令代替。

执行初始化命令:

rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "192.168.1.2:27017", priority: 2 },
    { _id: 1, host: "192.168.1.3:27017", priority: 1 }
  ]
})

参数说明:

  • _id: "rs0":必须与 mongod.conf 中的 replSetName 一致。
  • priority: 2(主)vs priority: 1(从):优先级高的节点在选举中更可能成为主节点,确保 192.168.1.2 优先当选。

执行后应返回 { "ok" : 1 }


第五步:验证副本集状态

等待约 10~30 秒后,在主节点上执行:

rs.status()

重点关注输出中的以下信息:

{
  "set" : "rs0",
  "members" : [
    {
      "name" : "192.168.1.2:27017",
      "stateStr" : "PRIMARY",    // ← 主节点
      ...
    },
    {
      "name" : "192.168.1.3:27017",
      "stateStr" : "SECONDARY",  // ← 从节点
      ...
    }
  ],
  "ok" : 1
}

也可以用更简洁的命令查看:

rs.isMaster()
// 或
rs.conf()

第六步:验证数据同步

主节点上写入测试数据:

use testdb
db.testcol.insertOne({ name: "hello", ts: new Date() })

从节点上读取(从节点默认不允许读,需先设置):

// 先从节点上执行,允许读取
db.getMongo().setReadPref('secondaryPreferred')
// 或
db.getMongo().setSecondaryOk()

// 然后查询
use testdb
db.testcol.find()

如果能看到刚才插入的数据,说明主从同步正常。


常见问题排查

从节点状态一直是 STARTUP 或 RECOVERING

# 检查从节点日志
tail -100 /var/log/mongodb/mongod.log | grep -i repl

常见原因:

  • 防火墙未开放 27017 端口
  • bindIp 仍为 127.0.0.1,从节点无法连接主节点
  • 两台机器时间不同步(你已配置 chrony,应该没问题)

想确认从节点同步延迟

在主节点上执行:

rs.printSecondaryReplicationInfo()

会显示从节点落后主节点多少秒。

想手动切换主节点

在主节点上执行:

rs.stepDown()

这会触发选举,192.168.1.3 因 priority 较低,正常情况下不会接管。如果你希望强制切换,可以临时调低主节点 priority:

var cfg = rs.conf()
cfg.members[0].priority = 0
rs.reconfig(cfg)

完整操作速查

192.168.1.2(主)和 192.168.1.3(从)都执行:
  ├── chown -R mongod:mongod /data/mongo
  ├── firewall-cmd --permanent --add-port=27017/tcp && firewall-cmd --reload
  ├── 编辑 /etc/mongod.conf(添加 replication.replSetName: rs0,修改 bindIp 和 dbPath)
  └── systemctl restart mongod

仅 192.168.1.2(主)执行:
  ├── mongosh
  ├── rs.initiate({_id:"rs0", members:[{_id:0,host:"192.168.1.2:27017",priority:2},{_id:1,host:"192.168.1.3:27017",priority:1}]})
  ├── rs.status()          // 确认 PRIMARY / SECONDARY
  └── rs.printSecondaryReplicationInfo()  // 确认同步状态

按以上步骤操作即可完成主从配置。如果过程中遇到具体报错,可以把日志贴出来帮你排查。