当主节点 (primary node in the replica set)节点降级或变得不可用时,副本集偶尔运行 选举。在选举期间,副本集在成功选出新的主节点 (primary node in the replica set)之前无法接受写入,但如果已配置,大多数读取操作可以在从节点上继续进行。
这种行为在罕见的故障转移或计划内维护期间是意料之中的。然而,频繁的选举(主节点 (primary node in the replica set)在正常运行期间经常发生变化)会导致重复的写入中断,在某些情况下,还会导致未提交数据的回滚。
此页面包含频繁选举的常见问题和解决方案,以确保快速诊断并避免应用程序写入中断。如果在查看以下部分后需要其他支持,联系技术支持。
先决条件检查
健康的集群仅在罕见的预期事件期间进行选举。选举通常在以下情况下发生:
初始设置
维护操作,例如
rs.stepDown()或rs.reconfig()新成员添加
rs.add()主节点不可用的时间超过配置的
timeout(默认为 10 秒)
replSetGetStatus通过在设立的时间段内(例如一小时内或全天)多次运行rs.status() 或 方法,验证您的部署在这些场景之外是否经历了频繁的选举。每次比较报告的主节点的_id 值,以追踪主节点 (primary node in the replica set)节点是否以及何时发生变化,即发生了选举。
注意
如果您在Ops Manager中看到 TOO_MANY_ELECTIONS警报,则可能遇到频繁选举。
检查日志消息
您还可以参阅部署的日志消息,查找组件() "c"值为ELECTION 的条目。如果您的日志在短时间内多次显示以下消息(例如每小时或每天多次出现且没有计划维护),则这通常表示由于网络不稳定、主机运行状况不佳或配置错误导致副本集不佳:
message | 说明 |
|---|---|
“正在开始选举,因为我们在选举超时期内没有看到主节点” | 当主节点 (primary node in the replica set)节点降级时由其他成员记录。 |
"transition to PRIMARY from SECONDARY" | 新的主节点 (primary node in the replica set)将接管。 |
“看不到该设立的大多数,放弃主节点 (primary node in the replica set)” | 之前的主节点 (primary node in the replica set)将成为从从节点(secondary node from replica set)。 |
常见问题和解决方案
以下部分介绍可能导致副本集意外频繁进行选举的常见问题。在联系支持人员之前,请检查以下陷阱是否会导致副本集频繁选举。
资源耗尽
密集型查询、大型聚合以及索引构建或备份等背景任务可能会导致高 CPU 使用率、磁盘延迟或故障以及内存压力。资源耗尽可能会导致频繁选举,因为主节点 (primary node in the replica set)可能会无响应或无法按时进程心跳。
低效查询
要检查您的部署是否由于查询效率低下而出现资源耗尽,请执行以下操作:
查找日志中组件(“c”)值为
COMMAND的条目。对于每个条目,
bytesRead字段表示给定命令读取的字节数。请注意具有较大bytesRead值的命令。如果低效查询的时间戳出现在多个选举的时间戳附近,则低效查询可能导致频繁选举。
使用以下资源来优化查询:
查看我们的 ESR 指南以创建新索引。
副本集配置错误
节点优先级
副本集不断进行选举,直到选出优先级最高的节点。如果您没有适当地设立节点优先级,则可能会更频繁地进行选举,导致意外的节点成为主节点 (primary node in the replica set)。
要检查每个节点的优先级值,运行replSetGetConfig 命令或rs.conf() 方法。以下示例显示了优先级配置不正确的副本集的rs.conf() 方法的输出:
rs.conf().members
[ { _id: 0, host: "rs0-0.example.net:27017", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 1, tags: { dc: "primaryDC" }, secondaryDelaySecs: Long(0), votes: 1 }, { _id: 1, host: "rs0-1.example.net:27017", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 10, tags: { dc: "remoteDC1" }, secondaryDelaySecs: Long(0), votes: 1 }, { _id: 2, host: "rs0-2.example.net:27017", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 9, tags: { dc: "remoteDC2" }, secondaryDelaySecs: Long(0), votes: 1 }, { _id: 3, host: "rs0-3.example.net:27017", arbiterOnly: false, buildIndexes: true, hidden: false, priority: 8, tags: { dc: "analyticsDC" }, secondaryDelaySecs: Long(0), votes: 1 } ]
在上面的示例中,当前主节点 (primary node in the replica set)的优先级低于其他三个节点。如果高优先从节点(secondary node from replica set)运行正常且处于 SECONDARY 状态,则它可以触发选举以接管主节点 (primary node in the replica set)。
确保为副本集成员正确配置优先级:
为您希望始终作为主节点 (primary node in the replica set)的提供服务服务器最高优先级
为其他成员分配默认或较低的优先级,以降低其成为主节点 (primary node in the replica set)的可能性
分配复制延迟高、优先级低的节点
副本集设置
要检查副本集配置设置,运行replSetGetConfig 命令或rs.conf() 方法。以下示例显示了electionTimeoutMillis 配置过低的副本集:
rs.conf().settings
{ chainingAllowed: true, heartbeatIntervalMillis: 2000, heartbeatTimeoutSecs: 10, electionTimeoutMillis: 1500, // lower than a single heartbeat cycle catchUpTimeoutMillis: 2000, getLastErrorModes: { }, getLastErrorDefaults: { w: 1, wtimeout: 0 }, replicaSetId: ObjectId("58858acc1f5609ed986b641b") }
确保 的值不太低。在上面的示例中, 值低于 。这意味着节点可以在完整的心跳间隔完成之前宣布主节点settings.electionTimeoutMillissettings.electionTimeoutMillissettings.heartbeatIntervalMillis (primary node in the replica set)“关闭”,从而导致不必要的选举。
网络分区或延迟
如果您的部署出现网络分区或节点出现心跳消息延迟,则从节点可能会错误地将主节点 (primary node in the replica set)视为不可用,并启动选举。
要验证您是否遇到网络分区,请执行以下操作:
检查日志中是否经常出现以下消息:
message说明“正在开始选举,因为我们在选举超时期内没有看到主节点”
从节点(secondary node from replica set)发起选举是因为它在配置的超时窗口内没有收到来自主节点 (primary node in the replica set)的心跳。
“看不到该设立的大多数,放弃主节点 (primary node in the replica set)”
主节点 (primary node in the replica set)已退出,因为它无法与大多数有投票权的从节点通信。
rs.status()从不同节点运行replSetGetStatus或 以显示哪些节点可访问的不同视图,这表明节点子集之间的分割。
为了帮助在分区后恢复连接,请执行以下操作:
检查防火墙配置,了解是否有任何可能区块成员之间通信的规则。
检查 DNS 主机名。
确保将IP解决添加到IP访问列表中。
验证分辨率
解决根本原因后,重新运行 rs.status(),确认不再出现频繁选举。输出仅显示一个处于主节点 (primary node in the replica set)状态的成员,并且主节点 (primary node in the replica set)在正常观察窗口内保持稳定,没有计划外更改。
您还可以查阅部署日志。在部署日志中查找上面列出的日志消息,以确保不会在短时间内多次发生选举。
为获得更多支持而收集的诊断信息
如果仍然无法解决问题,联系技术支持并提供以下诊断信息:
受影响时间段内的相关日志消息
rs.config()输出rs.status()输出