Oozie shell脚本动作

时间:2014-03-13 21:25:54

标签: bash hadoop hive oozie

我正在探索Oozie管理Hadoop工作流程的功能。我正在尝试设置一个shell动作来调用一些配置单元命令。我的shell脚本hive.sh看起来像:

#!/bin/bash
hive -f hivescript

hive脚本(已经独立测试)创建了一些表等等。我的问题是在哪里保留hivescript,然后如何从shell脚本中引用它。

我尝试了两种方法,首先使用本地路径,例如hive -f /local/path/to/file,并使用上面的相对路径hive -f hivescript,在这种情况下,我将我的hivescript保存在oozie应用中路径目录(与hive.sh和workflow.xml相同)并将其设置为通过workflow.xml转到分布式缓存。

使用这两种方法我收到错误消息: oozie Web控制台上的"Main class [org.apache.oozie.action.hadoop.ShellMain], exit code [1]"。另外,我尝试在shell脚本中使用hdfs路径,但就我所知,这不起作用。

我的job.properties文件:

nameNode=hdfs://sandbox:8020
jobTracker=hdfs://sandbox:50300   
queueName=default
oozie.libpath=${nameNode}/user/oozie/share/lib
oozie.use.system.libpath=true
oozieProjectRoot=${nameNode}/user/sandbox/poc1
appPath=${oozieProjectRoot}/testwf
oozie.wf.application.path=${appPath}

和workflow.xml:

<shell xmlns="uri:oozie:shell-action:0.1">

    <job-tracker>${jobTracker}</job-tracker>

    <name-node>${nameNode}</name-node>

    <configuration>

        <property>

            <name>mapred.job.queue.name</name>

            <value>${queueName}</value>

        </property>

    </configuration>

    <exec>${appPath}/hive.sh</exec>

    <file>${appPath}/hive.sh</file> 

    <file>${appPath}/hive_pill</file>

</shell>

<ok to="end"/>

<error to="end"/>

</action>

<end name="end"/>

我的目标是使用oozie通过shell脚本调用hive脚本,请提出你的建议。

2 个答案:

答案 0 :(得分:12)

Oozie工作流程一直很棘手的一点是执行bash脚本。 Hadoop被创建为大规模并行,因此架构的行为与您想象的完全不同。

当oozie工作流执行shell操作时,它将从您的作业跟踪器或群集中任何节点上的YARN接收资源。这意味着使用文件的本地位置将不起作用,因为本地存储仅在边缘节点上。如果作业碰巧在边缘节点上产生,那么它将起作用,但是任何其他时间它都会失败,并且这种分布是随机的。

为了解决这个问题,我发现最好将hdfs中需要的文件(包括sh脚本)放在lib空间或与我的工作流程相同的位置。

这是了解你想要实现的目标的好方法。

<shell xmlns="uri:oozie:shell-action:0.1">

    <exec>hive.sh</exec> 
    <file>/user/lib/hive.sh#hive.sh</file>
    <file>ETL_file1.hql#hivescript</file>

</shell>

您会注意到的一件事是exec只是hive.sh,因为我们假设文件将被移动到shell操作完成的基本目录

要确保最后一个注释为真,您必须包含文件的hdfs路径,这将强制oozie通过该操作分发该文件。 在你的情况下,hive脚本启动器应该只编码一次,并简单地提供不同的文件。由于我们有一对多的关系,hive.sh应该保存在lib中而不是与每个工作流程

最后你看到了这一行:

<file>ETL_file1.hql#hivescript</file>

这一行做了两件事。在#之前我们有文件的位置。它只是文件名,因为我们应该使用我们的工作流程分发我们独特的配置单元文件

user/directory/workflow.xml
user/directory/ETL_file1.hql

并且运行sh的节点将自动分发给它。最后,#之后的部分是变量名,我们在sh脚本中分配了两个变量名。这使您能够反复重复使用相同的脚本,并简单地将其提供给不同的文件。

HDFS目录说明,

如果文件嵌套在与工作流相同的目录中,那么您只需要指定子路径:

user/directory/workflow.xml
user/directory/hive/ETL_file1.hql

会屈服:

<file>hive/ETL_file1.hql#hivescript</file>

但如果路径在工作流目录之外,则需要完整路径:

user/directory/workflow.xml
user/lib/hive.sh

会产生:

<file>/user/lib/hive.sh#hive.sh</file>

我希望这对每个人都有帮助。

答案 1 :(得分:0)

http://oozie.apache.org/docs/3.3.0/DG_ShellActionExtension.html#Shell_Action_Schema_Version_0.2

如果您将shell脚本和配置单元脚本保存在工作流程中的某个文件夹中,则可以执行它。

请参阅示例中的命令

<exec>${EXEC}</exec>
        <argument>A</argument>
        <argument>B</argument>
        <file>${EXEC}#${EXEC}</file> <!--Copy the executable to compute node's current     working directory -->

你可以在文件中编写你想要的任何命令

您也可以直接使用hive动作

http://oozie.apache.org/docs/3.3.0/DG_HiveActionExtension.html