使用配置单元上下文的 Spark 作业在 oozie 中失败

Spark job that use hive context failing in oozie

在我们的一个管道中,我们使用 spark(java) 进行聚合,并使用 oozie 进行编排。 此管道使用以下行将聚合数据写入 ORC 文件。

HiveContext hc = new HiveContext(sc);
DataFrame modifiedFrame = hc.createDataFrame(aggregateddatainrdd, schema);

modifiedFrame.write().format("org.apache.spark.sql.hive.orc").partitionBy("partition_column_name").save(output);

当 oozie 作业中的 spark 操作被触发时,它会抛出以下异常

Failing Oozie Launcher, Main class [org.apache.oozie.action.hadoop.SparkMain], main() threw exception, org.apache.hadoop.hive.shims.HadoopShims.isSecurityEnabled()Z java.lang.NoSuchMethodError: org.apache.hadoop.hive.shims.HadoopShims.isSecurityEnabled()Z

但在多次重新运行工作流程后,同样取得了成功。

所有必要的 jar 在 运行 时间和编译时间都已到位。

这是我的第一个 spark 应用程序,我无法理解这个问题。

谁能帮助我更好地理解这个问题以及可能的解决方案。

"the same is getting succeeded after rerunning the workflow multiple times"

听起来您已经将 Spark 作业与 Hadoop 客户端编译/捆绑在一个 与 运行 集群不同的版本 中;结果,在 CLASSPATH 中存在冲突的 JAR,并且您的作业随机失败,具体取决于首先选择哪个 JAR。

为了确定,选择一个成功的 Oozie 作业和一个失败的作业,获取操作 的 "external ID"(标记为 job_*******_**** 但指的是 YARN ID application_******_****) 并检查两个作业的 YARN 日志。您应该看到 Java CLASSPATH 中 JAR 的实际顺序有所不同。

如果确实如此,则尝试组合

  • 在 Oozie 操作中,将 属性 oozie.launcher.mapreduce.user.classpath.first 设置为 true (对于 Spark 驱动程序)
  • 在 Spark 配置中,将 属性 spark.yarn.user.classpath.first 设置为 true (对于执行程序)

你可以猜到 user.classpath.first 意味着什么......!


但是,如果冲突的 JAR 实际上不在 Hadoop 客户端中,而是在 Oozie ShareLib 中,它可能不起作用。从 YARN 的角度来看,Oozie 是 "client",您不能在 Oozie 从其 ShareLib 发送的内容和它从您的 Spark 作业发送的内容之间设置优先级。

在那种情况下,您必须在您的 Java 项目 中使用适当的依赖项,并匹配您将 运行 反对的 Hadoop 版本 - - 这只是常识,你不觉得吗?!?