hidden节点必须同时设置hidden: true和priority: 0,否则可能意外成为primary;报表服务须用directconnection=true直连,禁用副本集自动发现;多hidden节点需差异化slavedelay避免同步风暴。

Hidden节点必须显式设置 hidden: true 且 priority: 0
只设 hidden: true 不够,MongoDB 允许 hidden 节点参与选举(只要 priority > 0),这会导致它意外成为 primary,破坏只读语义。必须同步将 priority 设为 0,才能确保它既不参选、也不被客户端发现。
常见错误是只改 hidden,忘了重置 priority;或者误用 votes: 0 却漏掉 priority: 0——votes 控制投票权,priority 才决定能否成为 primary。
-
hidden: true让该节点从 replica set 的 client discovery 中彻底消失(比如mongosh连接时不会自动包含它) -
priority: 0确保它永远无法被选为 primary,哪怕其他节点全部宕机 - 两者缺一不可,否则报表查询可能意外写入或触发主从切换
必须禁用自动发现,强制客户端直连 + directConnection=true
即使节点配置为 hidden,如果客户端使用副本集连接字符串(如 mongodb://host1:27017,host2:27017/?replicaSet=rs0),驱动仍可能通过心跳发现该节点并尝试路由读请求——尤其在某些旧版驱动中,hidden 并不完全阻断读路由逻辑。
正确做法是:报表服务只用单节点连接串,并显式启用 directConnection=true。
- ✅ 正确连接串:
mongodb://report-node:27017/?directConnection=true - ❌ 错误连接串:
mongodb://report-node:27017/?replicaSet=rs0(会触发自动发现,绕过 hidden 限制) - ❌ 错误连接串:
mongodb://host1:27017,host2:27017,report-node:27017/?replicaSet=rs0(暴露 hidden 节点给 driver)
多个 Hidden 节点需差异化配置 slaveDelay 避免同步风暴
如果你部署了多个 Hidden 节点用于不同用途(例如一个做小时级报表,一个做天级备份),它们的 slaveDelay 值不能相同。否则所有节点会在同一时刻向 primary 发起 oplog 拉取请求,造成主节点 CPU 和网络抖动,影响线上写入延迟。
建议按用途错开延迟值,且最小间隔不少于 300 秒:
- 报表专用节点:
"slaveDelay": 300(5 分钟延迟,兼顾实时性与负载) - 备份专用节点:
"slaveDelay": 86400(24 小时延迟,避免干扰) - 测试恢复节点:
"slaveDelay": 3600(1 小时,用于验证恢复流程)
注意:slaveDelay 是秒级整数,单位不是毫秒;设置后需执行 rs.reconfig() 生效,且该操作会触发一次选举(务必避开业务高峰)。
Hidden 节点仍参与 oplog 同步,但不响应读请求
Hidden 节点不是“离线备份”,它持续从 primary 或其他 secondary 拉取 oplog 并应用,数据始终是副本集的完整镜像。但它对客户端完全不可见——db.isMaster() 不返回它,rs.status() 中虽显示其状态,但 readPreference 无论设成 secondary 还是 nearest 都不会路由到它。
这意味着:你不能靠它做读写分离的“分担流量”,只能用于隔离场景;它的资源(CPU、内存、磁盘 IO)全用于同步和本地查询,不承担任何线上读压力。
容易被忽略的一点:Hidden 节点上的索引构建、聚合查询、$lookup 等操作,仍会消耗 replica set 的 oplog 回放带宽,若报表查询非常重(如全集合扫描 + 多阶段 pipeline),可能拖慢自身同步进度,导致 optimeDate 落后太多——这时要检查 rs.printSecondaryReplicationInfo() 输出的实际延迟。











