💡 本系列文章是 DolphinScheduler 由淺入深的教程,涵蓋搭建、二開迭代、核心原理解讀、運維和管理等一系列內容。適用於想對 DolphinScheduler瞭解或想要加深理解的讀者。
祝開卷有益。
本系列教程基於 DolphinScheduler 2.0.5 做的最佳化。(穩定版推薦使用3.1.9)
上篇回顧:海豚排程調優 | 正在執行的工作流(DAG)如何重新拉起失敗的任務(Task)
最近排程穩定執行一段時間了,有時間分享一下我們在使用海豚排程過程中遇到的問題和使用經驗,希望可以幫到大家。
今天分享的是任務被禁用出現的 Bug,包含兩個相關聯的問題。
已有的功能:在一個 DAG(工作流)中,存在節點被禁用的情況,表示該節點不會執行,執行到這個節點的時候,可以跳過這個節點繼續執行下游節點。
問題1[1]:在 Version 2.0.1 中,存在一個 BUG,如下圖所示,有 6 個節點,其中 test1_stop 和 test2_stop 節點是被禁用的。
從上圖可以看出,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 ,遍歷。
好的,問題1[1]到這裡就結束了,修復之後,test3 的直接上游節點 test2_stop 被禁用時,會繼續往上找到 test2, 如果 test2 還在執行,test3 不會立刻執行。
**負雜的系統,隨著不斷迭代,總會伴隨著小"驚喜"。繼續往下看 **
上述新增的邏輯,帶來了問題2[2],請看下圖:執行test_del_node 節點,選擇向後執行,按照正常的邏輯,會執行 test_del_node 和 test_del_node_36j 這兩個節點。但是 test_del_node_36j 一直不執行。
檢視 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 的判斷。
這樣,問題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 的生成,下次接著講,希望可以幫到你。
本文由 白鯨開源 提供釋出支援!