副本集使用选举来确定哪个集成员会成为主要成员。副本集可触发选举以响应各种事件,例如:
向副本集添加新节点,
使用
rs.stepDown()或rs.reconfig()等方法执行副本集维护,并且
在下图中,主节点的不可用时长已超过configured timeout并触发自动故障转移流程。剩余的从节点之一要求进行选举以选择新的主节点并自动恢复正常运行。
成功完成选举之前,副本集无法处理写入操作。如果将此类查询配置为在从节点上运行,则副本集可以继续提供读取查询。
The median time before a cluster elects a new primary should not typically exceed 12 seconds, assuming default replica configuration settings. This includes time required to mark the primary as unavailable and call and complete an election. You can tune this time period by modifying the settings.electionTimeoutMillis replication configuration option. Factors such as network latency may extend the time required for replica set elections to complete, which in turn affects the amount of time your cluster may operate without a primary. These factors are dependent on your particular cluster architecture.
您的应用程序连接逻辑应包括对自动故障转移和后续选举的容忍度。MongoDB 驱动程序可检测到主节点丢失,并一次性自动重试某些写入操作,从而为自动故障转移和选举提供额外的内置处理功能:
兼容的驱动程序将默认启用可重试写入
影响选举的因素和条件
复制选举协议
复制 protocolVersion: 1 缩短了副本集的故障转移时间并加快了对多个并行主节点的检测。
可以使用 catchUpTimeoutMillis 在更快的故障转移和保留 w:1 写入之间确定优先顺序。
有关 pv1 的详细信息,请参阅自管理副本集协议版本。
心跳
副本集成员每两秒向彼此发送一次心跳(网络探测(ping))。如果心跳在 10 秒内未返回,其他成员会将违规成员标记为不可访问。
节点优先级
副本集拥有稳定的主节点后,选举算法将“尽最大努力”尝试让具有最高可用 priority 的从节点发起选举。节点优先级会影响选举的时间和结果。优先级较高的从节点会更早调用选举,也更有可能获胜。但是,即使有更高优先级的从节点可用,也可以在短时间内将优先级较低的实例选为主节点。副本集成员继续发起选举,直到可用的最高优先级成员成为主节点。
优先级值为 0 的成员无法成为主节点,也无法寻求进行选举。有关详细信息,请参阅优先级 0 副本集成员。
镜像读取 (Mirrored Reads)
MongoDB 提供镜像读取,以预热可选举从节点的缓存。通过镜像读,主节点可以镜像其接收的一部分操作,并将其发送到可选举从节点的子集。预热从节点的缓存有助于在选举后更快地恢复性能。
有关详细信息,请参阅镜像读。
丢失数据中心
对于分布式副本集,一个数据中心的丢失可能会影响其他数据中心或多个数据中心内其余成员被选为主节点的能力。
如可能,跨数据中心分布副本集成员,即使数据中心丢失,剩余副本集成员之一成为新主节点的可能性最大化。
网络分区
网络分区可以将主节点分隔为包含少数节点的分区。当主节点检测到它只能看到副本集中少数的投票节点时,主节点会降级,而成为从节点。分区中可以与 majority 个投票节点(包括其自身)通信的分区成员可以独立进行选举,成为新的主节点。
投票权节点
副本集成员配置设置 members[n].votes 和成员 state 确定成员是否在选举中投票。
members[n].votes设置等于选举中的 1 票的所有副本集成员。要排除成员在选举中投票,请将该成员的members[n].votes配置值更改为0。
无投票权的成员
尽管无投票权成员不会在选举中投票,但这些成员持有副本集数据的副本,且可接受来自客户端应用程序的读取操作。
由于一个副本集最多可有 50 个成员,但其中仅有 7 个有投票权成员,因此可向副本集添加无投票权成员,以使成员人数超过 7 个。
非投票(即 votes 是 0) 节点的 priority 必须为 0。
例如,以下九个成员的副本集有七个有投票权的成员,两个无投票权的成员。
没有投票权的成员的 votes 和 priority 都等于 0:
{ "_id" : <num>, "host" : <hostname:port>, "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 0, "tags" : { }, "secondaryDelaySecs" : Long(0), "votes" : 0 }
重要
要想控制哪些成员成为主节点,切勿改变票数,而应修改 members[n].priority 选项。只有在特殊情况下可改变票数,比如,为了允许成员数超过七个。
要配置非投票节点,请参阅配置非投票自管理副本集节点。