我在Oozie中遇到过几个SparkAction作业的例子,其中大多数都是用Java编写的。我编辑了一下并在Cloudera CDH Quickstart 5.4.0(使用Spark版本1.4.0)中运行该示例。
workflow.xml
<workflow-app xmlns='uri:oozie:workflow:0.5' name='SparkFileCopy'>
<start to='spark-node' />
<action name='spark-node'>
<spark xmlns="uri:oozie:spark-action:0.1">
<job-tracker>${jobTracker}</job-tracker>
<name-node>${nameNode}</name-node>
<prepare>
<delete path="${nameNode}/user/${wf:user()}/${examplesRoot}/output-data/spark"/>
</prepare>
<master>${master}</master>
<mode>${mode}</mode>
<name>Spark-FileCopy</name>
<class>org.apache.oozie.example.SparkFileCopy</class>
<jar>${nameNode}/user/${wf:user()}/${examplesRoot}/apps/spark/lib/oozie-examples.jar</jar>
<arg>${nameNode}/user/${wf:user()}/${examplesRoot}/input-data/text/data.txt</arg>
<arg>${nameNode}/user/${wf:user()}/${examplesRoot}/output-data/spark</arg>
</spark>
<ok to="end" />
<error to="fail" />
</action>
<kill name="fail">
<message>Workflow failed, error
message[${wf:errorMessage(wf:lastErrorNode())}]
</message>
</kill>
<end name='end' />
</workflow-app>
job.properties
nameNode=hdfs://quickstart.cloudera:8020
jobTracker=quickstart.cloudera:8032
master=local[2]
mode=client
examplesRoot=examples
oozie.use.system.libpath=true
oozie.wf.application.path=${nameNode}/user/${user.name}/${examplesRoot}/apps/spark
Oozie工作流示例(在Java中)能够完成并完成其任务。
我使用Python / PySpark编写了spark-submit
作业。我尝试删除<class>
和jar
<jar>my_pyspark_job.py</jar>
但是当我尝试运行Oozie-Spark作业时,我在日志中出错:
Launcher ERROR, reason: Main class [org.apache.oozie.action.hadoop.SparkMain], exit code [2]
我想知道如果我使用Python / PySpark,我应该在<class>
和<jar>
标签中放置什么?
答案 0 :(得分:5)
我在oozie的火花动作中也经常挣扎。我正确设置了sharelib并尝试使用<spark-opts> </spark-opts>
标签中的--jars选项传递相应的jar,但无济于事。
我总是得到一些错误或另一个错误。我能做的最多就是通过spark-action在本地模式下运行所有java / python spark作业。
但是,我使用shell操作在所有执行模式下运行oozie中的所有spark作业。 shell操作的主要问题是shell作业被部署为&#39; yarn&#39;用户。如果您碰巧从纱线以外的用户帐户部署oozie spark作业,则最终会出现“权限被拒绝”错误(因为用户无法访问复制到/ user / yarn /中的spark程序集jar .SparkStaging目录)。解决此问题的方法是将HADOOP_USER_NAME环境变量设置为用于部署oozie工作流的用户帐户名。
以下是说明此配置的工作流程。我从ambari-qa用户部署我的oozie工作流程。
<workflow-app xmlns="uri:oozie:workflow:0.4" name="sparkjob">
<start to="spark-shell-node"/>
<action name="spark-shell-node">
<shell xmlns="uri:oozie:shell-action:0.2">
<job-tracker>${jobTracker}</job-tracker>
<name-node>${nameNode}</name-node>
<configuration>
<property>
<name>oozie.launcher.mapred.job.queue.name</name>
<value>launcher2</value>
</property>
<property>
<name>mapred.job.queue.name</name>
<value>default</value>
</property>
<property>
<name>oozie.hive.defaults</name>
<value>/user/ambari-qa/sparkActionPython/hive-site.xml</value>
</property>
</configuration>
<exec>/usr/hdp/current/spark-client/bin/spark-submit</exec>
<argument>--master</argument>
<argument>yarn-cluster</argument>
<argument>wordcount.py</argument>
<env-var>HADOOP_USER_NAME=ambari-qa</env-var>
<file>/user/ambari-qa/sparkActionPython/wordcount.py#wordcount.py</file>
<capture-output/>
</shell>
<ok to="end"/>
<error to="spark-fail"/>
</action>
<kill name="spark-fail">
<message>Shell action failed, error message[${wf:errorMessage(wf:lastErrorNode())}]</message>
</kill>
<end name="end"/>
</workflow-app>
希望这有帮助!
答案 1 :(得分:1)
您应该尝试配置Oozie Spark操作以在本地引入所需的文件。您可以使用文件标记进行制作:
<spark xmlns="uri:oozie:spark-action:0.1">
<job-tracker>${resourceManager}</job-tracker>
<name-node>${nameNode}</name-node>
<master>local[2]</master>
<mode>client</mode>
<name>${name}</name>
<jar>my_pyspark_job.py</jar>
<file>{path to your file on hdfs}/my_pyspark_job.py#my_pyspark_job.py</file>
</spark>
说明: 在YARN容器内运行的Oozie操作,由YARN在具有可用资源的节点上分配。在运行操作(实际上是“驱动程序”代码)之前,它将所有需要的文件(例如jar)本地复制到节点,分配给YARN容器的文件夹以放置其资源。因此,通过向oozie操作添加标记,您可以“告诉”您的oozie操作,将my_pyspark_job.py本地放入执行节点。
在我的情况下,我想运行一个运行python代码(hive-generic-partitioner.py)的bash脚本(run-hive-partitioner.bash),所以我需要节点上本地可访问的所有文件: / p>
<action name="repair_hive_partitions">
<shell xmlns="uri:oozie:shell-action:0.1">
<job-tracker>${jobTracker}</job-tracker>
<name-node>${nameNode}</name-node>
<exec>${appPath}/run-hive-partitioner.bash</exec>
<argument>${db}</argument>
<argument>${tables}</argument>
<argument>${base_working_dir}</argument>
<file>${appPath}/run-hive-partitioner.bash#run-hive-partitioner.bash</file>
<file>${appPath}/hive-generic-partitioner.py#hive-generic-partitioner.py</file>
<file>${appPath}/util.py#util.py</file>
</shell>
<ok to="end"/>
<error to="kill"/>
</action>
其中$ {appPath}是hdfs://ci-base.com:8020 / app / oozie / util / wf-repair_hive_partitions
所以这就是我的工作:
Files in current dir:/hadoop/yarn/local/usercache/hdfs/appcache/application_1440506439954_3906/container_1440506439954_3906_01_000002/
======================
File: hive-generic-partitioner.py
File: util.py
File: run-hive-partitioner.bash
...
File: job.xml
File: json-simple-1.1.jar
File: oozie-sharelib-oozie-4.1.0.2.2.4.2-2.jar
File: launch_container.sh
File: oozie-hadoop-utils-2.6.0.2.2.4.2-2.oozie-4.1.0.2.2.4.2-2.jar
正如你所看到的那样oozie(或者我认为实际的纱线)将所有需要的文件本地发送到temp文件夹,现在它可以运行它。
答案 2 :(得分:0)
我能够修复&#34;这个问题虽然引发了另一个问题。尽管如此,我仍然会发布它。
在Oozie容器日志的stderr中,它显示:
Error: Only local python files are supported
我找到了解决方案here
这是我最初的workflow.xml:
<spark xmlns="uri:oozie:spark-action:0.1">
<job-tracker>${resourceManager}</job-tracker>
<name-node>${nameNode}</name-node>
<master>local[2]</master>
<mode>client</mode>
<name>${name}</name>
<jar>my_pyspark_job.py</jar>
</spark>
我最初做的是将我希望作为spark-submit作业运行的Python脚本复制到HDFS。事实证明它需要本地文件系统中的.py脚本,所以我所做的就是引用我脚本的绝对本地文件系统。
<jar>/<absolute-local-path>/my_pyspark_job.py</jar>
答案 3 :(得分:0)
我们得到了同样的错误。如果你尝试将spark-assembly jar从'/path/to/spark-install/lib/spark-assembly*.jar'(取决于发行版)放到你的应用程序jar旁边的oozie.wf.application.path/lib
目录下它应该可以工作。