因此,在一个三节点的副本集中,其中两个备节点挂掉后,主节点会自动降备。 这样的设计主要是为了避免产生意外的数据不一致情况产生。
图- 主自动降备
第二个是_cancelAndRescheduleElectionTimeout_inlock函数,这里则是实现自动Failover的关键了,
它的逻辑中包含了一个选举定时器,代码如下:
- void ReplicationCoordinatorImpl::_cancelAndRescheduleElectionTimeout_inlock() {
- //如果上一个定时器已经启用了,则直接取消
- if (_handleElectionTimeoutCbh.isValid()) {
- LOG(4) << "Canceling election timeout callback at " << _handleElectionTimeoutWhen;
- _replExecutor.cancel(_handleElectionTimeoutCbh);
- _handleElectionTimeoutCbh = CallbackHandle();
- _handleElectionTimeoutWhen = Date_t();
- }
- //仅支持3.2后的V1版本
- if (!isV1ElectionProtocol()) {
- return;
- }
- //仅备节点可执行
- if (!_memberState.secondary()) {
- return;
- }
- ...
- //是否可以选举
- if (!_rsConfig.getMemberAt(_selfIndex).isElectable()) {
- return;
- }
- //检测周期,由 electionTimeout + randomOffset
- //randomOffset是随机偏移量,默认为 0~0.15*ElectionTimeoutPeriod = 0~1.5s
- Milliseconds randomOffset = _getRandomizedElectionOffset();
- auto now = _replExecutor.now();
- auto when = now + _rsConfig.getElectionTimeoutPeriod() + randomOffset;
-
- LOG(4) << "Scheduling election timeout callback at " << when;
- _handleElectionTimeoutWhen = when;
- //触发调度,时间为 now + ElectionTimeoutPeriod + randomOffset
- _handleElectionTimeoutCbh =
- _scheduleWorkAt(when,
- stdx::bind(&ReplicationCoordinatorImpl::_startElectSelfIfEligibleV1,
- this,
- StartElectionV1Reason::kElectionTimeout));
- }
上面代码展示了这个选举定时器的逻辑,在每一个检测周期中,定时器都会尝试执行超时回调,
而回调函数指向的是_startElectSelfIfEligibleV1,这里面就实现了主动发起选举的功能,
如果心跳响应成功,通过cancelAndRescheduleElectionTimeout调用将直接取消当次的超时回调(即不会发起选举)
如果心跳响应迟迟不能成功,那么定时器将被触发,进而导致备节点发起选举并成为新的主节点!
同时,这个回调方法(产生选举)被触发必须要满足以下条件:
- 当前是备节点
- 当前节点具备选举权限
- 在检测周期内仍然没有与主节点心跳成功
这其中的检测周期略大于electionTimeout(10s),加入一个随机偏移量后大约是10-11.5s内,猜测这样的设计是为了错开多个备节点主动选举的时间,提升成功率。
最后,将整个自动选举切换的逻辑梳理后,如下图所示:
图-超时自动选举
业务影响评估
副本集发生主备切换的情况下,不会影响现有的读操作,只会影响写操作。 如果使用3.6及以上版本的驱动,可以通过开启retryWrite来降低影响。
但是如果主节点是属于强制掉电,那么整个 Failover 过程将会变长,很可能需要在Election定时器超时后才被副本集感知并恢复,这个时间窗口会在12s以内。
此外还需要考虑客户端或mongos对于副本集角色的监视和感知行为。但总之在问题恢复之前,对于原主节点的任何读写都会发生超时。
因此,对于极为重要的业务,建议最好在业务层面做一些防护策略,比如设计重试机制。 (编辑:威海站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|