Oozie 让其他分叉操作继续以防万一失败但在加入后终止
Oozie let other forked actions continue in case one fails but terminate after the join
我有一个工作流程,分为 3 个操作。
<start to="PARALLEL_PROCESS_FORK"/>
<fork name="MY_FORK">
<path start="START_PARALLEL_PATH_1"/>
<path start="START_PARALLEL_PATH_2"/>
<path start="START_PARALLEL_PATH_3"/>
</fork>
这三个路径启动了一系列操作,每个操作都可能失败。
我发现简单的事情是创建以下 DAG。在 join
之后还有其他操作。下面的 DAG 的问题是,如果我到达 kill
节点,例如在顶部路径,所有其他路径也将在到达 join
.
之前被杀死
然而,这不是想要的流程。我需要的是,如果并行路径上的操作失败,我只需要终止该执行路径,但其他路径应继续执行直到加入。例如,如果操作 A2
失败,操作 A3
将被跳过,但 C1
、C2
、C3
将被执行。 join
之后的决策节点将检测到发生错误并终止。
你知道我是怎么做到的吗?
选项 1:使用 wf:actionExternalStatus
在这种情况下,想法很简单:使用节点的外部状态来确定下一步要做什么。
节点的状态可以是运行、KILLED、FAILED、SUCCEEDED、空(如果节点已被跳过)或“FAILED/KILLED”。所以我们需要检查 KILLED 或 FAILED 状态。鉴于默认 Oozie EL functions 的限制,我们可以使用以下构造:
<decision name="check-if-action-failed">
<switch>
<case to="kill_A">
${replaceAll(wf:actionExternalStatus('A1'), '.*FAILED.*|.*KILLED.*', 'FAILED') eq 'FAILED'} or
${replaceAll(wf:actionExternalStatus('A3'), '.*FAILED.*|.*KILLED.*', 'FAILED') eq 'FAILED'}
</case>
<case to="kill_C">
${replaceAll(wf:actionExternalStatus('C1'), '.*FAILED.*|.*KILLED.*', 'FAILED') eq 'FAILED'} or
${replaceAll(wf:actionExternalStatus('C2'), '.*FAILED.*|.*KILLED.*', 'FAILED') eq 'FAILED'}
</case>
<default to="next-action"/>
</switch>
</decision>
选项 2:使用 shell-脚本
我在下面显示的解决方法是在 KO
的节点中使用 Shell 脚本。这些是我们希望并行分支逐步执行但让其他并行分支到达连接的节点。
所以在上图中我们有 KO_A
和 KO_C
。这将调用一个 shell 脚本 echo-ko.sh
,它将简单地执行:
echo "STATUS=KO"
在 Oozie 术语中,这些节点将如下所示:
KO_A
<action name="KO_A" retry-max="3" retry-interval="2">
<shell xmlns="uri:oozie:shell-action:0.3">
<exec>echo-ko.sh</exec>
<file>\path\to\script\echo-ko.sh</file>
<capture-output/>
</shell>
<ok to="my-join"/>
<error to="some-fail-node"/>
</action>
加入后决定
<decision name="check-branch-ko">
<switch>
<case to="kill_A">
${wf:actionData('KO_A')['STATUS'] eq 'KO'}
</case>
<!-- Other cases -->
<default to="..."/>
</switch>
</decision>
我有一个工作流程,分为 3 个操作。
<start to="PARALLEL_PROCESS_FORK"/>
<fork name="MY_FORK">
<path start="START_PARALLEL_PATH_1"/>
<path start="START_PARALLEL_PATH_2"/>
<path start="START_PARALLEL_PATH_3"/>
</fork>
这三个路径启动了一系列操作,每个操作都可能失败。
我发现简单的事情是创建以下 DAG。在 join
之后还有其他操作。下面的 DAG 的问题是,如果我到达 kill
节点,例如在顶部路径,所有其他路径也将在到达 join
.
然而,这不是想要的流程。我需要的是,如果并行路径上的操作失败,我只需要终止该执行路径,但其他路径应继续执行直到加入。例如,如果操作 A2
失败,操作 A3
将被跳过,但 C1
、C2
、C3
将被执行。 join
之后的决策节点将检测到发生错误并终止。
你知道我是怎么做到的吗?
选项 1:使用 wf:actionExternalStatus
在这种情况下,想法很简单:使用节点的外部状态来确定下一步要做什么。
节点的状态可以是运行、KILLED、FAILED、SUCCEEDED、空(如果节点已被跳过)或“FAILED/KILLED”。所以我们需要检查 KILLED 或 FAILED 状态。鉴于默认 Oozie EL functions 的限制,我们可以使用以下构造:
<decision name="check-if-action-failed">
<switch>
<case to="kill_A">
${replaceAll(wf:actionExternalStatus('A1'), '.*FAILED.*|.*KILLED.*', 'FAILED') eq 'FAILED'} or
${replaceAll(wf:actionExternalStatus('A3'), '.*FAILED.*|.*KILLED.*', 'FAILED') eq 'FAILED'}
</case>
<case to="kill_C">
${replaceAll(wf:actionExternalStatus('C1'), '.*FAILED.*|.*KILLED.*', 'FAILED') eq 'FAILED'} or
${replaceAll(wf:actionExternalStatus('C2'), '.*FAILED.*|.*KILLED.*', 'FAILED') eq 'FAILED'}
</case>
<default to="next-action"/>
</switch>
</decision>
选项 2:使用 shell-脚本
我在下面显示的解决方法是在 KO
的节点中使用 Shell 脚本。这些是我们希望并行分支逐步执行但让其他并行分支到达连接的节点。
所以在上图中我们有 KO_A
和 KO_C
。这将调用一个 shell 脚本 echo-ko.sh
,它将简单地执行:
echo "STATUS=KO"
在 Oozie 术语中,这些节点将如下所示:
KO_A
<action name="KO_A" retry-max="3" retry-interval="2">
<shell xmlns="uri:oozie:shell-action:0.3">
<exec>echo-ko.sh</exec>
<file>\path\to\script\echo-ko.sh</file>
<capture-output/>
</shell>
<ok to="my-join"/>
<error to="some-fail-node"/>
</action>
加入后决定
<decision name="check-branch-ko">
<switch>
<case to="kill_A">
${wf:actionData('KO_A')['STATUS'] eq 'KO'}
</case>
<!-- Other cases -->
<default to="..."/>
</switch>
</decision>