2

我在 ambari-views ui 中为我的工作流程中的 oozie 和 sample.sh 文件创建工作流程,运行后出现错误。例如,当我将 shell 主体更改为简单命令时,echo 1没有出现此错误,请告诉我

2:34,752  WARN ShellActionExecutor:523 - SERVER[dlmaster02.sic] USER[root] GROUP[-] TOKEN[] APP[shell-wf] JOB[0000043-180630152627142-oozie-oozi-W] ACTION[0000043-180630152627142-oozie-oozi-W@shell-node] Launcher ERROR, reason: Main class [org.apache.oozie.action.hadoop.ShellMain], main() threw exception, Cannot run program "sample.sh" (in directory "/hadoop/yarn/local/usercache/root/appcache/application_1531029096800_0022/container_e18_1531029096800_0022_01_000002"): error=2, No such file or directory
2018-07-21 16:42:34,753  WARN ShellActionExecutor:523 - SERVER[dlmaster02.sic] USER[root] GROUP[-] TOKEN[] APP[shell-wf] JOB[0000043-180630152627142-oozie-oozi-W] ACTION[0000043-180630152627142-oozie-oozi-W@shell-node] Launcher exception: Cannot run program "sample.sh" (in directory "/hadoop/yarn/local/usercache/root/appcache/application_1531029096800_0022/container_e18_1531029096800_0022_01_000002"): error=2, No such file or directory
java.io.IOException: Cannot run program "sample.sh" (in directory "/hadoop/yarn/local/usercache/root/appcache/application_1531029096800_0022/container_e18_1531029096800_0022_01_000002"): error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at org.apache.oozie.action.hadoop.ShellMain.execute(ShellMain.java:110)
    at org.apache.oozie.action.hadoop.ShellMain.run(ShellMain.java:69)
    at org.apache.oozie.action.hadoop.LauncherMain.run(LauncherMain.java:75)
    at org.apache.oozie.action.hadoop.ShellMain.main(ShellMain.java:59)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.oozie.action.hadoop.LauncherMapper.map(LauncherMapper.java:231)
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:54)
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:453)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:343)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:170)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:422)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1869)
    at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:164)
Caused by: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
    at java.lang.ProcessImpl.start(ProcessImpl.java:134)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    ... 17 more

我的工作流程的 xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<workflow-app xmlns="uri:oozie:workflow:0.5" name="test">
    <start to="shell_1"/>
    <action name="shell_1">
        <shell xmlns="uri:oozie:shell-action:0.3">
            <job-tracker>${resourceManager}</job-tracker>
            <name-node>${nameNode}</name-node>
            <configuration>
                <property>
                    <name>Group</name>
                    <value>hadoop</value>
                </property>
            </configuration>
            <exec>/user/ambari-qa/sample.sh</exec>
            <file>/user/ambari-qa/sample.sh</file>
        </shell>
        <ok to="end"/>
        <error to="kill"/>
    </action>
    <kill name="kill">
        <message>${wf:errorMessage(wf:lastErrorNode())}</message>
    </kill>
    <end name="end"/>
</workflow-app>
4

3 回答 3

3

我遇到了同样的问题,但就我而言,根本原因是由于 shell 脚本的 CRLF 行分隔符(\r\n)。

当我将 shell 脚本的行分隔符更改为 LF ( \n) 时,此问题得到解决。

注意:在 Windows 中使用默认设置的 IntelliJ 时,CRLF( \r\n) 将是默认的行分隔符

于 2020-06-10T21:31:45.950 回答
2

当您通过作为 Ambari 视图的Ambari 工作流管理工具执行此操作时,您应该编辑 shell 操作,向下滚动到“高级属性”,然后添加要运行的“文件”,例如“/user/admin/hello .sh" 必须是 hdfs 中的文件。如果你不这样做,那么文件不会被复制到纱线容器的文件缓存中,所以你会得到“找不到文件”。

如果您这样做,然后“提交”作业,转到仪表板,然后打开作业,然后单击“定义”选项卡,您应该会看到图形工具<file>在工作流程中添加了一个节点:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><workflow-app xmlns="uri:oozie:workflow:0.5" name="helloworldshell">
    <start to="shell_1"/>
    <action name="shell_1">
        <shell xmlns="uri:oozie:shell-action:0.3">
            <job-tracker>${resourceManager}</job-tracker>
            <name-node>${nameNode}</name-node>
            <exec>hello.sh</exec>
            <file>/user/admin/hello.sh</file>
            <capture-output/>
        </shell>
        <ok to="end"/>
        <error to="kill"/>
    </action>
    <kill name="kill">
        <message>${wf:errorMessage(wf:lastErrorNode())}</message>
    </kill>
    <end name="end"/>
</workflow-app>

重要的几行是:

            <exec>hello.sh</exec>
            <file>/user/admin/hello.sh</file>

类似的节点<file>/x/y/z</file>会导致将 hdfs 文件从 hdfs 上的该路径复制到远程数据节点服务器上正在运行的 shell 操作的当前工作目录中,该操作在纱线容器中运行。然后它可以由 将在最终 JVM<exec>z</exec>中查找它的元素使用。$PWD设置为运行工作的$PWD最终主机上生成的临时位置。对于工作流作业的每次运行,这可能是不同的服务器和不同的文件夹。

请注意,运行任何 oozie 工作流程的“纱线容器”与docker 容器完全不同。它是一个带有托管类路径和安全管理器的 JVM,可防止您读取任意 linux 文件。在大型集群上,任何操作都可以在任何节点上运行,因此文件必须通过 HDFS 分发。有一种缓存机制可以确保文件在主机上本地缓存。yarn 设置的安全管理器只会让您访问在文件缓存中正确设置的文件,这些文件由<file>XML 中的一个或多个节点定义。

虽然如果您不了解底层技术,工作流 GUI 似乎非常有用,但该手册在调试时并不是很有帮助。在边缘节点的命令行上执行一些“hello world”作业是个好主意,首先将示例 xml 放入 hdfs 文件夹,然后使用命令行工具启动作业。工作流 Web UI 只是在顶部添加了一个图形使用界面。

通常,您所做的是将文件放入您保存的工作流程下方的子文件夹中:

$ tree shdemo
shdemo
├── bin
│   ├── hello.sh
└── workflow.xml

在工作流程中使用文件的相对路径而不是绝对路径:

<file>bin/hello.sh#hello.sh</file>

表示将#文件符号链接到 $PWD 是可选的,但可能会有所帮助。对于复杂的工作流程,您可以为不同的文件类型(例如,'bin'、'config'、'data')设置不同的子文件夹。然后,您可以将许多<file?条目添加到您的工作流 XML 中。最后,将所有这些文件夹复制到运行它的 hdfs 中:

 # copy up the workflow files and subfolders into hdfs
 hdfs dfs -copyFromLocal -f shdemo /user/$(whoami)/my_workflows

 # launch it from that location within hdfs
 oozie job -oozie $OOZIE_URL -config shdemo-job.properties -run

您会注意到,当您使用 Workflow GUI 提交作业时,您必须将您的工作流“保存”到 HDFS 文件夹。就是那个 hdfs 文件夹,您可以在其中添加一个bin/hello.sh您将如上所述引用的文件夹。再一次,Web UI 只是命令行技术的皮肤。一旦你有一个简单的命令行工作,你可以将它导入工作流 GUI,编辑它,然后将它保存回相同的 hdfs 位置。

于 2020-04-26T07:39:03.300 回答
1

请尝试以下方法并告诉我您的结果。

<exec>sample.sh</exec>
<file>${nameNode}/user/ambari-qa/sample.sh</file>

它需要一个带有 Namenode 的完整路径才能访问,否则它将寻找默认路径,这里的错误表明该脚本在默认路径中不可用。

于 2018-12-10T12:43:20.047 回答