加入收藏 | 设为首页 | 会员中心 | 我要投稿 核心网 (https://www.hxwgxz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

MongoDB一次节点宕机引发的思考

发布时间:2019-11-04 17:40:30 所属栏目:编程 来源:java架构coid
导读:简介 最近一个 MongoDB 集群环境中的某节点异常下电了,导致业务出现了中断,随即又恢复了正常。 通过ELK 告警也监测到了业务报错日志。 运维部对于节点下电的原因进行了排查,发现仅仅是资源分配上的一个失误导致。 在解决了问题之后,大家也对这次中断的

上面的代码中存在的一些细节:

  • 心跳的超时时间,在_topCoord.prepareHeartbeatRequestV1方法中就已经设定好了
  • 具体的算法就是:
  1. **hbTimeout=_rsConfig.getHeartbeatTimeoutPeriodMillis() - alreadyElapsed** 

其中heartbeatTimeoutPeriodMillis是可配置的参数,默认是10s, 那么alreadyElapsed是指此前连续心跳失败(最多2次)累计的消耗时间,在心跳成功响应或者超过10s后alreadyElapsed会置为0。因此可以判断,随着心跳失败次数的增加,超时时间会越来越短(心跳更加密集)

心跳执行的回调,指向自身的_handleHeartbeatResponse方法,该函数实现了心跳响应成功、失败(或是超时)之后的流程处理。

ReplicationCoordinatorImpl::_handleHeartbeatResponse方法的代码片段:

  1. void ReplicationCoordinatorImpl::_handleHeartbeatResponse( 
  2.  const ReplicationExecutor::RemoteCommandCallbackArgs& cbData, int targetIndex) { 
  3.  LockGuard topoLock(_topoMutex); 
  4.  // remove handle from queued heartbeats 
  5.  _untrackHeartbeatHandle(cbData.myHandle); 
  6.  ... 
  7.  //响应成功后 
  8.  if (responseStatus.isOK()) { 
  9.  networkTime = cbData.response.elapsedMillis.value_or(Milliseconds{0}); 
  10.  const auto& hbResponse = hbStatusResponse.getValue(); 
  11.  // 只要primary 心跳响应成功,就会重新调度 electionTimeout定时器 
  12.  if (hbResponse.hasState() && hbResponse.getState().primary() && 
  13.  hbResponse.getTerm() == _topCoord->getTerm()) { 
  14.  //取消并重新调度 electionTimeout定时器 
  15.  cancelAndRescheduleElectionTimeout(); 
  16.  } 
  17.  } 
  18.  ... 
  19.  //调用topCoord的processHeartbeatResponse方法处理心跳响应状态,并返回下一步执行的Action 
  20.  HeartbeatResponseAction action = _topCoord->processHeartbeatResponse( 
  21.  now, networkTime, target, hbStatusResponse, lastApplied); 
  22.  ... 
  23.  //调度下一次心跳,时间间隔采用action提供的信息 
  24.  _scheduleHeartbeatToTarget( 
  25.  target, targetIndex, std::max(now, action.getNextHeartbeatStartDate())); 
  26.  //根据Action 执行处理 
  27.  _handleHeartbeatResponseAction(action, hbStatusResponse, false); 

这里省略了许多细节,但仍然可以看到,在响应心跳时会包含这些事情的处理:

对于主节点的成功响应,会重新调度 electionTimeout定时器(取消之前的调度并重新发起)

通过_topCoord对象的processHeartbeatResponse方法解析处理心跳响应,并返回下一步的Action指示

根据Action 指示中的下一次心跳时间设置下一次心跳定时任务

处理Action指示的动作

那么,心跳响应之后会等待多久继续下一次心跳呢? 在 TopologyCoordinatorImpl::processHeartbeatResponse方法中,实现逻辑为:

如果心跳响应成功,会等待heartbeatInterval,该值是一个可配参数,默认为2s;

如果心跳响应失败,则会直接发送心跳(不等待)。

(编辑:核心网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读