将 CLASSPATH 添加到 Oozie 工作流作业

Add CLASSPATH to Oozie workflow job

我在 Java 中编写了访问 Hive 表的 SparkSQL,并使用 spark-submit 打包了一个可以 运行 的 jar 文件。

现在我想 运行 这个 jar 作为 Oozie 工作流(和协调器,如果我让工作流工作的话)。当我尝试这样做时,作业失败了,我进入了 Oozie 作业日志

java.lang.NoClassDefFoundError: org/apache/hadoop/hive/conf/HiveConf

我所做的是在 $HIVE_HOME/lib 中查找包含 class 的 jar,将那个 jar 复制到我的 Oozie 工作流根路径的 lib 路径中并将其添加到workflow.xml 在 Spark 操作中:

<spark-opts> --jars lib/*.jar</spark-opts>

但这会导致另一个 java.lang.NoClassDefFoundError 指向另一个丢失的 class,所以我再次进行了查找 jar 和复制的过程,运行 工作和相同事情就这样结束了。看起来它需要依赖我的 Hive 库中的许多 jar。

我不明白的是,当我使用 jar 在 shell 中使用 spark-submit 时,它 运行 没问题,我可以 SELECT 并插入到我的 Hive 中表。只有当我使用 Oozie 时才会发生这种情况。当包含在 Oozie 工作流作业中时,看起来 Spark 再也看不到 Hive 库了。有人可以解释这是怎么发生的吗?

如何向 Oozie 路径添加或引用必要的 classes/jar?

我正在使用 Cloudera Quickstart VM CDH 5.4.0、Spark 1.4.0、Oozie 4.1.0。

在 Oozie 中避免 ClassPath not found 异常的更好方法是,在集群中安装 Oozie SharedLib,并更新共享位置中的 Hive/Pig jar {Some Times Existing Jar in Oozie Shared Location use与产品罐子不匹配。} hdfs://hadoop:50070/user/oozie/share/lib/ 更新后,请传递一个参数 "oozie.use.system.libpath = true"

这些将通知 oozie 从 Hadoop 共享位置读取 Jars。

一旦您通过设置参数 "true" 提及共享位置,您就无需在 workflow.xml

中一一提及所有和每个罐子

通常 "edge node"(您可以连接到的那个)在默认的 CLASSPATH 中预装和引用了很多东西。 但是 Hadoop "worker nodes" 可能是准系统,只预装了核心 Hadoop 库。

因此,您可以等待几年,让 Oozie 将 Spark 依赖项正确打包到 ShareLib 中,并使用 "blablah.system.libpath" 标志。

[编辑] 如果基本 Spark 功能正常但您在 Hive 格式接口上失败,则指定 ShareLibs 的 list 包括"HCatalog" 例如

action.sharelib.for.spark=spark,hcatalog

或者,您可以找出 Spark 实际使用了哪些 JAR 和配置文件,将它们上传到 HDFS,并在 下的 Oozie Action 中引用它们(所有这些,一个一个地),以便它们在 YARN 容器的工作目录中的 运行 时间下载。

[编辑] 也许 ShareLib 包含 JAR 但不包含配置文件;那么您所要做的就是 upload/download 是一个有效配置文件列表(Hive、Spark 等)