2021-12-13---2021SC@SDUSC---DolphinScheduler(12)

2021-12-13
2021SC@SDUSC

2021-12-13-DolphinScheduler(12)

worker的故障转移

/**
 * failover worker tasks
 *
 * 1. kill yarn job if there are yarn jobs in tasks.
 * 2. change task state from running to need failover.
 * 3. failover all tasks when workerHost is null
 * @param workerHost			worker host
 * @param needCheckWorkerAlive	need check worker alive
 * @throws Exception			exception
 */
private void failoverWorker(String workerHost, boolean needCheckWorkerAlive) throws Exception {
	logger.info("start worker[{}] failover ...", workerHost);

	List<TaskInstance> needFailoverTaskInstanceList = processDao.queryNeedFailoverTaskInstances(workerHost);
	for(TaskInstance taskInstance : needFailoverTaskInstanceList){
		if(needCheckWorkerAlive){
			if(!checkTaskInstanceNeedFailover(taskInstance)){
				continue;
            }
		}

		ProcessInstance instance = processDao.findProcessInstanceDetailById(taskInstance.getProcessInstanceId());
		if(instance!=null){
			taskInstance.setProcessInstance(instance);
		}
		// only kill yarn job if exists , the local thread has exited
		ProcessUtils.killYarnJob(taskInstance);

		taskInstance.setState(ExecutionStatus.NEED_FAULT_TOLERANCE);
		processDao.saveTaskInstance(taskInstance);
	}
	logger.info("end worker[{}] failover ...", workerHost);
}
首先根据worker的IP找到对应的任务实例,如果该实例不需要故障转移则继续下一个任务实例的检测;
如果需要,则找到对应的流程定义实例,将其与任务实例关联;
只去掉yarn作业,其他作业的本地线程已经退出;
设置任务实例的状态为ExecutionStatus.NEED_FAULT_TOLERANCE。

看到这里发现worker的故障转移就是设置任务实例的状态。
worker就是等对应的线程池安全退出才stop,其实就是让正在执行的任务实例继续执行完毕,也就是处理ExecutionStatus.NEED_FAULT_TOLERANCE状态的任务实例。

ExecutionStatus.NEED_FAULT_TOLERANCE

全局搜索ExecutionStatus.NEED_FAULT_TOLERANCE

if(task.getState()==ExcutionStatus.SUCCESS){
     completeTasjKist.put(task.getName());
     continue;
}
//node fails,retry first,and then execute the failure process
if(task.getState().typeIsFailure()){
    
    if(task.getState()==ExecutionStatus.NEED_FAULT_TOLERANCE){       
           this.recoverToleranceFaultTaskList.add(task);
    }
    if(task.taskCanRetry()){
           addTaskToStandByList(task);
   
    }else{
    //node failure, based on failure strategy
         errorTaskList.put(task.getName(),task);
         completeTaskList.put(task.gameName(),task);
         if(processInstance.getFailureStrategy()==FailureStrategy.END){
               killTheOtherTasks();
         }
    }
}

发现对ExecutionStatus.NEED_FAULT_TOLERANCE做过的唯一重要的判断是:
如果作业失败且需要故障转移,就把他放到recoverToleranceFaultTaskList列表中。
但跟踪代码才发现recoverToleranceFaultTaskList就是用来预警的。

/**
 * determine if you can try again
 * @return can try result
 */
public boolean taskCanRetry() {
    if(this.isSubProcess()){
        return false;
    }
    if(this.getState() == ExecutionStatus.NEED_FAULT_TOLERANCE){
        return true;
    }else {
        return (this.getState().typeIsFailure()
            && this.getRetryTimes() < this.getMaxRetryTimes());
    }
}
taskCanRetry中,如果是ExecutionStatus.NEED_FAULT_TOLERANCE状态,则不管重试了多少次,一定可以重试。就是说如果发现某个作业是故障转移状态,则失败的时候一定可以重试。
if(task.getState().typeIsFailure()){
    if(task.getState() == ExecutionStatus.NEED_FAULT_TOLERANCE){
        this.recoverToleranceFaultTaskList.add(task);
    }
    if(task.taskCanRetry()){
        addTaskToStandByList(task);
    }else{
        // node failure, based on failure strategy
        errorTaskList.put(task.getName(), task);
        completeTaskList.put(task.getName(), task);
        if(processInstance.getFailureStrategy() == FailureStrategy.END){
            killTheOtherTasks();
        }
    }
    continue;
}
上面是MasterExecThread.runProcess中的一段代码,其逻辑就是如果当前作业失败,且可以重试,就把作业添加到readyToSubmitTaskList队列中再次执行。而ExecutionStatus.NEED_FAULT_TOLERANCE就是属于可以重试。

因此DolphinScheduler故障转移的逻辑:

    worker如果与zookeeper连接超时,则停止心跳,停止获取任务,等待所有任务实例执行结束(正常或失败)并更新数据库状态
    master如果与zookeeper连接超时,则停止心跳,停止获取流程定义实例,停止调度所有流程定义实例
    master如果发现某个流程定义实例中的任务实例失败且属于ExecutionStatus.NEED_FAULT_TOLERANCE状态,则重新运行。

假设master/worker与zookeeper的连接超时,则master/worker出现了问题,应该发生故障转移。

master/worker与zookeeper的连接超时有两种可能,
master/worker的网络有问题、zookeeper有问题。
如果是master/worker的网络有问题则MySQL的读写也会有问题,意味着任务实例的状态更新可能有问题,此时发生故障转移没问题;
如果是zookeeper服务本身有问题,则所有的master/worker可能都会有问题,即使发生故障转移意义不是特别大。

zookeeper存在的意义就是分布式锁,而不应是度量心跳,
DolphinScheduler把流程定义、实例等信息保存到了数据库,那么心跳应该去度量与数据库的连接,而不是去度量与zookeeper的连接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗的仓鼠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值