Oozie 让其他分叉操作继续,以防万一失败但在加入后终止

问题描述

我有一个工作流程,我将其分为 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 之前被终止。

Current execution

然而,这不是理想的流程。我需要的是,如果并行路径上的操作失败,我只需要终止该执行路径,但其他路径应该继续直到加入。例如,如果操作 A2 失败,将跳过操作 A3,但会执行 C1C2C3join 之后的决策节点将检测到错误发生并终止。

Desired solution

你知道我是怎么做到的吗?

解决方法

选项 1:使用 wf:actionExternalStatus

在这种情况下,想法很简单:使用节点的外部状态来确定下一步要做什么。

enter image description here

节点的状态可以是 RUNNING、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') eq 'FAILED'}
    </case>
    <case to="kill_C">
      ${replaceAll(wf:actionExternalStatus('C1'),'FAILED') eq 'FAILED'} or
      ${replaceAll(wf:actionExternalStatus('C2'),'FAILED') eq 'FAILED'}
    </case>
    <default to="next-action"/>
  </switch>
</decision>

选项 2:使用 shell 脚本

我在下面展示的解决方法是在 KO 的节点中使用 Shell 脚本。这些是我们希望并行分支逐步执行的节点,但让其他并行分支到达连接。 enter image description here

因此在上图中,我们有 KO_AKO_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>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...