跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

MongoDB副本集如何添加仲裁节点_使用rs.addArb()优化低成本高可用架构

MongoDB 4.0+ 已移除 rs.addArb(),必须用 rs.add({host: "h:p", arbiterOnly: true}) 在主节点执行;仲裁节点仅投票、不存数据,需跨故障域部署并验证 rs.status() 中 stateStr 和 health。 rs.addArb() 不能直接加仲裁节点,必须用完整配置对象 很多人执行
rs.addArb("host:27017")
报错
no such cmd: addArb
或
not master
,根本原因是:MongoDB 从 4.0 开始已移除独立的
rs.addArb()
命令,它从来就不是“函数”,而是
rs.add()
的语法糖——且仅在旧版本(≤3.6)中存在。现在必须显式传入带
arbiterOnly: true
的配置对象。 正确写法:
rs.add({host: "arbiter.example.com:27017", arbiterOnly: true})
错误写法:
rs.addArb("arbiter.example.com:27017")
(命令不存在) 必须在主节点(primary)上执行,且该节点状态为
PRIMARY
(可用
rs.status().myState
确认) 仲裁节点主机必须能被所有副本集成员通过 hostname 解析并建立 TCP 连接(端口 27017 默认) 仲裁节点不存数据,但对选举权重和故障域有实际影响 仲裁节点(arbiter)只参与投票,不复制数据、不服务读请求、不占用磁盘空间——听起来是“零成本高可用”,但它的加入会实质性改变选举逻辑和容错边界。 副本集总票数 = 数据节点票数 + 仲裁节点票数(默认各为 1),必须 > 总票数一半才能选出 primary;加 1 个 arbiter 可让 2 节点集群具备故障转移能力(2+1=3 票,允许 1 节点宕机) 但若把 arbiter 和某个数据节点部署在同一物理机或同一可用区,等于没扩大故障域——网络分区时可能同时失联,反而降低可用性 仲裁节点的
priority
始终为 0,无法被设为 hidden / delayed,也不能配置
tags
;这些字段传了也会被忽略 添加后需验证状态,常见失败场景有三类 执行
rs.add(...)
返回成功不代表仲裁节点已生效。必须立刻检查
rs.status()
输出中的
members[n].stateStr
和
health
字段。 MongoDB For Windows v3.5.4 MongoDB For Windows v3.5.4 下载
"stateStr": "ARBITER"
且
"health": 1
→ 正常
"stateStr": "DOWN"
→ 网络不通或目标端口未监听(确认
mongod
是否运行、
bindIp
是否包含该网卡、防火墙是否放行)
"stateStr": "REMOVED"
→ 被自动踢出,通常因心跳超时(默认 10 秒),可临时调大
heartbeatTimeoutSecs
(不推荐长期使用) 如果
rs.status()
中看不到新成员,可能是配置未持久化——检查
rs.conf().members
是否已更新;若没更新,说明
rs.add()
执行失败但未报错(罕见,多因权限不足或 config server 模式误用) 低成本架构下,仲裁节点不是万能解,要防单点依赖反模式 用 1 个数据节点 + 1 个仲裁节点撑起“高可用”看似省事,但实际是伪高可用:一旦数据节点宕机,整个集群不可写;仲裁节点宕机虽不影响服务,但会让剩余节点失去多数票,下次数据节点故障时无法自动选举。 真正低成本可靠方案是:2 数据节点 + 1 仲裁节点(跨机房/可用区部署),或直接用 3 个数据节点(无仲裁,读写分离更灵活) 仲裁节点不能替代备份——它不存数据,崩溃后无法恢复任何历史状态 监控必须覆盖
rs.status().members[n].lastHeartbeatRecv
,比单纯 ping 端口更能反映真实连通性 仲裁节点的配置项极少,但它的存在会悄悄改写整个副本集的决策边界;加之前先想清楚:你到底是在补足投票权,还是在掩盖架构单点。

相关文章