[EDP] 添加 Oozie Shell Action 作业类型

https://blueprints.launchpad.net/sahara/+spec/add-edp-shell-action

Oozie shell actions 提供了很大的灵活性,并能使用户根据需要轻松定制和扩展 Sahara EDP 的功能。例如,shell action 可以用于管理集群上的 hdfs,对从 Sahara 启动的另一个作业进行预处理或后处理,或者从一个专门的启动器运行数据处理作业,该启动器执行 Sahara 否则无法提供的额外配置(例如,为 Java 作业设置特殊的 classpath)。

问题描述

如今,如果用户发现 Sahara EDP 中的限制妨碍了他们执行所需的处理,他们有几种选择

  • 使用指定的密钥对通过 ssh 登录到集群节点并手动执行处理。这可能并非对所有用户都可用。

  • 编写 Java 应用程序来执行自定义处理,并将其作为 EDP 中的 Java 作业运行。这可行,但是我们作为开发人员知道 Java 并不常用作脚本语言;它有点太笨重,而且并非每个人都知道它。

  • 修改 Sahara 源代码。精通的用户可能会自行扩展 Sahara EDP 以获得所需的功能。但是,并非每个人都是开发人员,或者没有足够的时间来理解 Sahara 以做到这一点。

  • 提交错误或蓝图,并等待 Sahara 团队解决它。

然而,shell actions 的存在将使用户能够轻松解决他们自己的问题。使用 shell action,用户可以将文件与用 bash、Python 等编写的脚本捆绑在一起,并在集群上执行它。

以下是一个真实案例,可以用 shell action 轻松解决

https://blueprints.launchpad.net/sahara/+spec/edp-add-hbase-lib

在上面的蓝图中,我们要求在 Sahara 中添加额外的功能,以方便用户使用,但使用 shell action 用户可以自行解决此问题。可以编写一个简单的 bash 脚本来启动 Java 应用程序,如下所示

#!/bin/bash
java -cp HBaseTest.jar:`hbase classpath` HBaseTest

在这种情况下,用户会将脚本和 Java 应用程序与 shell 作业关联为作业二进制文件,Sahara 将执行该脚本。

在类似的情况下,Sahara EDP 本身使用 Python 包装器围绕 spark-submit 来运行 Spark 作业。shell action 使这些类型的启动器易于供最终用户使用。

提议的变更

添加一个由 Oozie EDP 引擎实现的 Shell 作业类型。(其他 EDP 引擎,例如 Spark 或 Storm 引擎,可以共享此类作业的基本 shell 命令实现,但这将是另一个 CR)。

Shell 作业可以使用作业执行中的现有 mainslibs 字段。在 mains 中标识的脚本将是 Sahara 运行的脚本,libs 中的文件将是 Oozie 捆绑在工作目录中的支持文件。

与其他作业类型一样,shell actions 将支持在作业执行的现有 job_configs 字段中传递的 configsargs。在 Oozie 工作流中用 <configuration> 标签指定 configs 中的值,这些值将在 Oozie 创建的文件中可用。使用 <argument> 标签指定 args,并按指定顺序传递给 shell 脚本。

在下面的参考部分中,有一个 shell action 工作流的简单示例。工作流中有三个标签,对于 Sahara 而言,这些标签是 Shell action 所独有的,应该由 Sahara 处理

  • <exec>script</exec> 这标识了 shell action 应该执行的命令。此处指定的值将是 mains 中标识的脚本的名称。从技术上讲,这可以是路径上的任何命令,但如果我们要求它是一个脚本,可能会更简单。根据一些实验,如果从工作目录运行脚本,可以避免路径评估的一些细微之处

  • <file>support.jar</file> 这标识了将包含在工作目录中的支持文件。对于 libs 中命名的每个文件以及 mains 中标识的脚本,都将有一个 <file> 标签。

    (请注意,<file> 标签可以在 Oozie 中的任何工作流中使用,但目前 Sahara 根本没有实现它。它对于 shell action 是必需的,这就是为什么在此处提及它。是否要在 Sahara 中添加对 <file> 标签的常规支持是另一个讨论)

  • <env-var>NAME=VALUE</env-var> env-var 标签在 shell 的环境中设置一个变量。最有可能的是,我们可以使用现有的 job_configs 字段中的 params 字典来传递 env-var 值,即使我们想在 UI 中将它们标记为“环境变量”。

替代方案

什么都不做。

数据模型影响

此更改添加了一个新的作业类型,但由于作业类型存储为字符串,因此不应产生任何数据模型影响。

REST API 影响

仅对作业类型的验证代码进行更改

其他最终用户影响

部署者影响

可能存在与参考部分中列出的 URL 中的 Shell Action Caveats,要点 2 相关的安全注意事项。

尚不清楚在 Sahara EDP 中,启动 TaskTracker 的用户是否与提交工作流的用户不同。这需要调查 - Sahara 如何向 Oozie 客户端进行身份验证?Oozie 服务器使用哪个用户来部署作业?

开发者影响

Sahara-image-elements impact

Sahara-dashboard / Horizon 影响

我们需要一个新的表单来提交 Shell 作业类型。该表单应允许指定主脚本、支持库、配置值、参数和环境变量(从 UI 的角度来看,环境变量与 params 完全相同)。

实现

负责人

主要负责人

egafford

其他贡献者

tmckay

工作项

  • 调查上述用户问题(在 Sahara 中运行 shell actions 的用户是谁,有什么影响?)

  • workflow_creator 目录下的 Oozie EDP 引擎组件中添加一个 Shell 作业类型和实现

  • 更新作业验证例程以处理 Shell 作业类型

  • 为 Shell 作业添加集成测试

  • 更新 EDP 文档以描述 Shell 作业类型

  • 添加 Shell 作业提交的 UI 表单

依赖项

测试

  • 单元测试以涵盖 Shell 作业的创建

  • 集成测试以涵盖运行简单的 shell 作业

文档影响

需要更新 EDP 部分的文档

参考资料

http://blog.cloudera.com/blog/2013/03/how-to-use-oozie-shell-and-java-actions/

一个简单的 Shell action 工作流如下所示

<workflow-app xmlns='uri:oozie:workflow:0.3' name='shell-wf'>
  <start to='shell1' />
  <action name='shell1'>
      <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>default</value>
              </property>
          </configuration>
          <exec>doit.sh</exec>
          <argument>now</argument>
          <env-var>VERSION=3</env-var>
          <file>HBaseTest.jar</file>
          <file>doit.sh</file>
      </shell>
      <ok to="end" />
      <error to="fail" />
  </action>
  <kill name="fail">
      <message>oops!</message>
  </kill>
  <end name='end' />
</workflow-app>