我有一个PySpark应用程序,我想用Oozie调度,使用shell操作。我的submit-application.sh
脚本只是初始化一个Python virtualenv(存在于所有工作节点上),并调用application.py
Python应用程序脚本。application.py
脚本是一个PySpark应用程序,它自带一个本地Python模块,我们称之为foobar
,该模块可以简单地导入并在整个代码中使用。
因此,我有一个类似于下面的目录结构:
.
├── foobar
│ ├── config.py
│ ├── foobar.py
│ └── __init__.py
├── application.DEV.ini
├── application.PROD.ini
├── application.py
├── requirements.txt
└── submit-application.sh
我尝试使用Oozie工作流来打包所有脚本和本地模块文件,但是很明显,无论我使用了什么配置,它们总是以扁平化的形式交付,转储到容器的root目录中。这会阻止Python脚本加载本地模块,从而导致ModuleNotFoundError: No module named 'foobar'
错误。
有没有办法告诉Oozie把文件工件放在一个子目录中呢?看起来#
符号被忽略了。
这是我的Oozie workflow.xml
文件
<workflow-app name="Data-Extraction-WF" xmlns="uri:oozie:workflow:0.5">
<global>
<job-tracker>${jobTracker}</job-tracker>
<name-node>${nameNode}</name-node>
</global>
<start to="Data-Extraction"/>
<action name="Data-Extraction">
<shell xmlns="uri:oozie:shell-action:1.0">
<exec>submit-application.sh</exec>
<file>app/__init__.py#app/__init__.py</file>
<file>app/config.py#app/config.py</file>
<file>app/foobar.py#app/foobar.py</file>
<file>application.DEV.ini#application.DEV.ini</file>
<file>application.PROD.ini#application.PROD.ini</file>
<file>application.py#application.py</file>
<file>submit-application.sh#submit-application.sh</file>
<capture-output/>
</shell>
<ok to="success"/>
<error to="failure"/>
</action>
<kill name="failure">
<message>Workflow failed, error message: [${wf:errorMessage(wf:lastErrorNode())}]</message>
</kill>
<end name="success"/>
</workflow-app>
1条答案
按热度按时间v8wbuo2f1#
最后我创建了一个从HDFS获取文件的 Package 器脚本,并在Oozie工作流中简单地使用它。除了工作流的HDFS位置之外,步骤(子目录)也被传递给这个脚本,然后它下载整个目录并在其中执行运行脚本。
这是我的
execute_workflow_step.sh
脚本:它从工作流的HDFS目录下载step目录并执行其运行脚本: