深入解析Apache DolphinScheduler容錯機制

海豚调度發表於2024-10-22

簡述

Apache Dolphinscheduler Master和Worker都是支援多節點部署,無中心化的設計。

  • Master主要負責是流程DAG的切分,最終透過RPC將任務分發到Worker節點上以及Worker上任務狀態的處理
  • Worker主要負責是真正任務的執行,最後將任務狀態彙報給Master,Master進行狀態處理

那問題來了:

  1. Master掉了怎麼辦?它是負責流程例項的管理的。這樣Worker就沒有辦法給它彙報任務狀態,當然它也不能做狀態處理了?
  2. Worker掉了又怎麼辦?要知道Worker是真正任務執行的載體,它如果掉了。Master要怎麼處理?

來來來,一張圖說清楚它們。

容錯

file

總結

其實說白了就是如果Master掉了,其他Master分散式鎖來對Master進行容錯。也就是流程例項由之前的down掉的Master切換到要接管的Master上,這個時候是需要給Worker下發新Master的host的,讓Worker可以重新給新Master上報資訊

而Worker掉了就是任務的重試,但是任務重試之前是有前提的,那就是要kill掉正在執行YARN上的任務,當前DS做不到。為什麼?因為對於在非客戶端分離模式下,是需要ProcessBuilder的waitFor一直等待客戶端程序退出的。而applicationId的解析是在客戶端程序退出(也就是waitFor退出)之後做的。

那意思就是說只能等待程式執行完畢,我才能獲取到applicationId。

org.apache.dolphinscheduler.server.master.service.WorkerFailoverService#killYarnTask

private void killYarnTask(TaskInstance taskInstance, ProcessInstance processInstance) {
    try {
        if (!masterConfig.isKillApplicationWhenTaskFailover()) {
            return;
        }
        if (StringUtils.isEmpty(taskInstance.getHost()) || StringUtils.isEmpty(taskInstance.getLogPath())) {
            return;
        }
        TaskExecutionContext taskExecutionContext = TaskExecutionContextBuilder.get()
                .buildWorkflowInstanceHost(masterConfig.getMasterAddress())
                .buildTaskInstanceRelatedInfo(taskInstance)
                .buildProcessInstanceRelatedInfo(processInstance)
                .buildProcessDefinitionRelatedInfo(processInstance.getProcessDefinition())
                .create();
        // only kill yarn/k8s job if exists , the local thread has exited
        log.info("TaskInstance failover begin kill the task related yarn or k8s job");
        ILogService iLogService =
                SingletonJdkDynamicRpcClientProxyFactory.getProxyClient(taskInstance.getHost(), ILogService.class);
        GetAppIdResponse getAppIdResponse =
                iLogService.getAppId(new GetAppIdRequest(taskInstance.getId(), taskInstance.getLogPath()));
        ProcessUtils.killApplication(getAppIdResponse.getAppIds(), taskExecutionContext);
    } catch (Exception ex) {
        log.error("Kill yarn task error", ex);
    }
}

怎麼辦?回顧 1.3.3 版本,是LoggerServer和Master是分離模式的,所以只要Master節點有yarn客戶端,是可以透過master對yarn上的applicationId進行幹掉的。而現在怎麼辦?

兩種解決思路 :

  1. Master上kill,使用yarn rest api
curl -X PUT -d '{"state":"KILLED"}' \
    -H "Content-Type: application/json" \
    http://xx.xx.xx.xx:8088/ws/v1/cluster/apps/application_1694766249884_1098/state?user.name=hdfs

注意 : 需要加使用者。

  1. Worker上kill
    這個是需要標識該任務是容錯任務,然後在任務重試執行的時候,排程到指定的Worker上。需要先kill當前執行的applicationId,然後再任務重試。其實這裡有一個最佳化點就是,是Worker掉了,但是任務還在,所以需要判斷的是yarn上的狀態,如果異常,再kill也不遲,而不是上來就kill。如果是RUNNING,等待就好,可以設定等待超時時間。

轉載自journey

原文連結:https://segmentfault.com/a/1190000045084857

本文由 白鯨開源 提供釋出支援!

相關文章