当一个人被杀时,Oozie分叉会杀死所有行动

时间:2015-07-08 12:13:40

标签: join parallel-processing workflow fork oozie

我在Oozie中使用fork / join,以便并行一些子工作流操作。 我的workflow.xml如下所示:

<workflow-app name="myName" xmlns="uri:oozie:workflow:0.5"
<start to="fork1"/>
<kill name="Kill">
    <message>Action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
    </kill>

<fork name="fork1">
    <path start="subworkflow1"/>
    <path start="subworkflow2"/>
</fork>
<join name="Completed" to="End"

<action name="subworkflow1">
    <sub-workflow>
        <app-path>....</app-path>
        <propagate-configuration/>
        <configuration>
            <property>
                <name>....</name>
                <value>....</value>
            </property>
        </configuration>
    </sub-workflow>
    <ok to="Completed"/>
    <error to="Completed"/>
</action>

<action name="subworkflow2">
    <sub-workflow>
        <app-path>....</app-path>
        <propagate-configuration/>
        <configuration>
            <property>
                <name>....</name>
                <value>....</value>
            </property>
        </configuration>
    </sub-workflow>
    <ok to="Completed"/>
    <error to="Completed"/>
</action>

<end name="End"></workflow-app>

当subworkflow1被杀死时(由于某种原因失败),它也会杀死subworkflow2。我希望这两个动作是平行的,但不是依赖的。

在我的工作流程中,当workflow1被杀死时,我看到workflow2也被杀死,但我的应用程序成功了(我在Oozie仪表板上检查它 - &gt; HUE中的工作流程)。

在这种情况下,我希望subworkflow1将被终止,subworkflow2将成功,而我并不关心我的整个应用程序会说些什么。

  • 在我的情况下,subworkflow1需要比subworkflow2更长的时间,所以当我检查我的应用程序结束时,我看到虽然它说subworkflow1 + 2被杀了,我的应用程序成功了,但是真正发生的是subworkflow2完成了它的部分尽管如此,它后来被杀死了(它一直在运行&#39;直到叉子的所有路径完成它们的运行)。所以workflow2完成了它的部分而不是被杀死因为workflow1被杀......

即使同一个分叉中的其他路径被杀死,我应该怎么做才能让每个路径获得自己的状态并继续运行?

3 个答案:

答案 0 :(得分:6)

我最近也遇到过这个问题。找到了让oozie表现我想要的方式。

您的分叉操作的错误值可能等于您的连接名称。这将跳过该特定分叉执行路径中的任何后续操作。然后,您的加入&#34;到&#34; value可以将控制发送到决策节点。该决策节点应检查wf:lastErrorNode()的值。如果值为空字符串,请继续根据需要处理工作流程。如果该值不是空字符串,则发生错误,您可以将控制发送到kill节点。

以下是一个例子:

<start to="forkMe"/>
<fork name="forkMe">
    <path start="action1"/>
    <path start="action2"/>
</fork>
<action name="action1">
    ...
    <ok to="joinMe"/>
    <error to="joinMe"/>
</action>
<action name="action1">
    ...
    <ok to="joinMe"/>
    <error to="joinMe"/>
</action>
<join name="joinMe" to="decisionMe"/>
<decision name="decisionMe">
  <switch>
     <case to="end">
        ${wf:lastErrorNode() eq ""}
     </case>
     <default to="error-mail"/>
 </switch>
</decision>
<action name="error-mail">
    ...
    <ok to="fail"/>
    <error to="fail"/>
</action>
<kill name="fail">
    <message>Job failed:
        message[${wf:errorMessage(wf:lastErrorNode())}]
    </message>
</kill>
<end name="end"/>

答案 1 :(得分:0)

处理它的几种方法。

1)您可以独立提交这两个子工作流,而不是包含它们的大型工作流。

2)将retry添加到子工作流程1,子工作流程2在最后一次子工作流程1失败之前不会被杀死。如果设置了长的重试间隔,则当上次1次失败时,2已经完成,并且2的状态将保持正常。 kill不会影响状态正常的操作。

这个问题。在我的工作流程中,当workflow1被杀死时,我看到workflow2也被杀死了,但我的应用程序成功了(我在Oozie仪表板上检查它 - &gt; HUE中的工作流程)。

A: <error to="Completed"/> (如果已完成的节点最终未到达终止节点)此设置将让oozie认为工作流程已成功完成,即使发生此操作时出现错误。

答案 2 :(得分:0)

我通过将分叉操作设置为“错误到”以加入节点来解决此问题。然后将join节点设置为跟着ssh节点。

<action name="ssh-50c1">
    <ssh xmlns="uri:oozie:ssh-action:0.1">
        <host>${SSH_USER_HOST}</host>
        <command>${wf:lastErrorNode() eq null}</command>
        <capture-output/>
    </ssh>
    <ok to="End"/>
    <error to="Kill"/>
</action>

使用shell节点的替代方法可能是可行的,并且更合适,但是它对我不起作用。 另外,您可以使用决策节点(检查wf:lastErrorNode())来完成相同的操作,但是这样一来,您将无法重试工作流,因为决策节点即使失败也会被标记为成功。