| 
                         因此,在一个三节点的副本集中,其中两个备节点挂掉后,主节点会自动降备。 这样的设计主要是为了避免产生意外的数据不一致情况产生。 
 
图- 主自动降备 
第二个是_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对于副本集角色的监视和感知行为。但总之在问题恢复之前,对于原主节点的任何读写都会发生超时。 
因此,对于极为重要的业务,建议最好在业务层面做一些防护策略,比如设计重试机制。                         (编辑:滁州站长网) 
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! 
                     |