扩容前需先执行rs.status()和rs.conf()确认成员数量、host、_id及version;新增节点时须递增version,避免nodenotfound错误;推荐5数据节点或3数据+2仲裁结构,禁用偶数投票节点;启动新实例参数须一致;添加节点需等同步完成;rs.reconfig()需全量替换配置,注意_id唯一、votes和priority设置;扩容后须验证复制延迟、连接字符串包含全部节点并执行db.ismaster()确认生效。

扩容前必须确认副本集当前状态
别急着加节点,先连上主节点执行 rs.status() 和 rs.conf()。重点看两件事:一是 members 数组里当前有几个成员、各自 host 和 _id 是什么;二是 version 字段值,后续 rs.reconfig() 必须基于这个版本号递增,否则会报错 NodeNotFound 或 InvalidReplicaSetConfig。
常见错误是直接在旧配置上追加新成员后调用 rs.reconfig(),但没更新 version —— MongoDB 会拒绝该操作,且不提示具体原因,只返回模糊错误。
新增两个节点:一个数据节点 + 一个仲裁节点(或第二个数据节点)
生产环境推荐「3 数据 + 2 仲裁」或「5 数据」结构,但不能出现偶数个投票节点(如 2 数据 + 2 仲裁),否则选举可能卡在平票。优先选 5 个数据节点,除非资源受限。
- 启动新 mongod 实例时,
--replSet名称、--bind_ip(建议用主机名而非127.0.0.1)、--dbpath路径必须与现有节点一致,端口不能冲突 - 如果新加的是仲裁节点,用
rs.addArb("hostname:port");如果是数据节点,用rs.add({host: "hostname:port", priority: 0})(若不想它参选主节点) - 不要在
rs.initiate()后立刻加节点——必须等所有已有节点状态为PRIMARY或SECONDARY,且syncing完成(rs.status().members[n].stateStr === "SECONDARY"且optimeDate接近当前时间)
重配置时绕不开的三个参数陷阱
rs.reconfig() 不是简单追加,而是全量替换配置。最容易出错的是这三个字段:
-
_id:每个成员的_id必须全局唯一,且不能重复使用已删除节点的旧_id,否则同步会失败 -
votes:默认为 1,但仲裁节点必须显式设为"votes": 1,数据节点若设为 0 就彻底失去投票权(慎用) -
priority:范围是 0–100,0 表示永不参选,但 priority=0 的节点仍可同步数据;若想让它参与选举但权重低,设为 1–50 即可
示例片段(非完整配置):
rs.reconfig({<br> _id: "rs1",<br> version: 5,<br> members: [<br> { _id: 0, host: "node1:27017", priority: 3 },<br> { _id: 1, host: "node2:27017", priority: 2 },<br> { _id: 2, host: "node3:27017", priority: 1 },<br> { _id: 3, host: "node4:27017", votes: 1 },<br> { _id: 4, host: "node5:27017", votes: 1 }<br> ]<br>})
扩容后必须验证复制延迟和读写路由
加完节点不代表就稳了。真正容易被忽略的是这三件事:
- 用
rs.printSlaveReplicationInfo()看新节点的sync lag是否持续 >1s;若 lag 持续增长,说明网络或磁盘 IO 不足,不是配置问题 - 客户端连接字符串里必须包含全部 5 个节点地址(如
mongodb://node1:27017,node2:27017,...),否则 driver 可能无法感知新节点,故障转移会失效 - 执行
db.isMaster()确认hosts数组含 5 项,passives或arbiters字段存在且正确——这是判断配置是否生效的最直接依据
节点数变多后,oplog 增长速度和选举耗时都会变化,别跳过压测环节。











