海豚排程調優 | 如何解決任務被禁用出現的Bug

海豚调度發表於2024-06-27

💡 本系列文章是 DolphinScheduler 由淺入深的教程,涵蓋搭建、二開迭代、核心原理解讀、運維和管理等一系列內容。適用於想對 DolphinScheduler瞭解或想要加深理解的讀者。

祝開卷有益。

本系列教程基於 DolphinScheduler 2.0.5 做的最佳化。(穩定版推薦使用3.1.9

上篇回顧:海豚排程調優 | 正在執行的工作流(DAG)如何重新拉起失敗的任務(Task)

最近排程穩定執行一段時間了,有時間分享一下我們在使用海豚排程過程中遇到的問題和使用經驗,希望可以幫到大家。

file

今天分享的是任務被禁用出現的 Bug,包含兩相關聯的問題。

已有的功能:在一個 DAG(工作流)中,存在節點被禁用的情況,表示該節點不會執行,執行到這個節點的時候,可以跳過這個節點繼續執行下游節點。

問題1[1]:在 Version 2.0.1 中,存在一個 BUG,如下圖所示,有 6 個節點,其中 test1_stop 和 test2_stop 節點是被禁用的。

file

從上圖可以看出,test3 依賴 test1_stop 和 test2_stop。但是執行的時候,發現 test2 節點還在執行呢,test3 就已經執行了,並沒有等待所有上游節點執行結束

上述問題如何解決呢?

新增一個遞迴向上查詢間接依賴的方法(如果是上游節點被禁用了,繼續向上查詢)

新增 setIndirectDepList 方法,如果該節點的上游被禁用了,則繼續尋找上游。最終把所有的上游加到 indirectDepCodeList 這裡。

/**
 * This function is specially used to handle the dependency situation where the parent node is a prohibited node.
 * When the parent node is a forbidden node, the dependency relationship should continue to be traced
 *
 * @param taskCode            taskCode
 * @param indirectDepCodeList All indirectly dependent nodes
 */
private void setIndirectDepList(String taskCode, List<String> indirectDepCodeList) {
    TaskNode taskNode = dag.getNode(taskCode);
    List<String> depCodeList = taskNode.getDepList();
    for (String depsNode : depCodeList) {
        if (forbiddenTaskMap.containsKey(depsNode)) {
            setIndirectDepList(depsNode, indirectDepCodeList);
        } else {
            indirectDepCodeList.add(depsNode);
        }
    }
}

在 isTaskDepsComplete 方法中,引用這個 list ,遍歷。

file

好的,問題1[1]到這裡就結束了,修復之後,test3 的直接上游節點 test2_stop 被禁用時,會繼續往上找到 test2, 如果 test2 還在執行,test3 不會立刻執行。

**負雜的系統,隨著不斷迭代,總會伴隨著小"驚喜"。繼續往下看 **

上述新增的邏輯,帶來了問題2[2],請看下圖:執行test_del_node 節點,選擇向後執行,按照正常的邏輯,會執行 test_del_node 和 test_del_node_36j 這兩個節點。但是 test_del_node_36j 一直不執行。

file

檢視 Master 日誌發現,在提交 test_del_node_36j 這個節點的時候,出現了submit standby task error這個錯誤,拿到本地 debug 之後,發現在 setIndirectDepList 中出現了 NPE。最後定位到下面兩行程式碼:

TaskNode taskNode = dag.getNode(taskCode);
List<String> depCodeList = taskNode.getDepList();

透過分析,最後發現是因為test_del_node_36j的節點的直接上游節點被禁用了,按照 setIndirectDepList 裡面的邏輯,存在被禁用的節點,是會繼續往上找的,找到間接依賴。

dag 在工作流啟動的時候,根據 startNode 生成了關係圖(dag),dag 裡面只有兩個節點: test_del_node 和 test_del_node_36j 。此時遞迴查詢test_del_node_36j上游節點的上游節點的時候,報了 NEP。

處理方式也比較簡單,加一個 null 的判斷。

file

這樣,問題2[2]就解決了。

總結

  • 問題1 在 2.0.3-release 中得到修復。

  • 問題2 在 3.0.5-release 中得到修復。

如果不想升級的小夥伴,可以自行根據自己的版本,進行修改。

需要注意的是:

  • 2.x 版本,對應的程式碼檔案是 WorkflowExecuteThread.java

  • 3.x 版本,對應的程式碼檔案是 WorkflowExecuteRunnable.java

以上就是任務被禁用出現的Bug關聯的兩個問題的分享,如果有任何疑問,都可以與我交流,同樣社群也推薦大家使用3.1.9版本,這是相對比較穩定的版本,上文中,還提到了 dag 的生成,下次接著講,希望可以幫到你。

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

相關文章