我编写了用Java访问Hive表的SparkSQL,并打包了一个可以使用spark-submit
运行的jar文件。
现在我想把这个jar作为Oozie工作流程(和协调员,如果我让工作流程工作)。当我尝试这样做时,工作失败,我进入Oozie工作日志
java.lang.NoClassDefFoundError: org/apache/hadoop/hive/conf/HiveConf
我所做的是在$HIVE_HOME/lib
中查找包含该类的jar,将该jar复制到我的Oozie工作流根路径的lib
路径中,并将其添加到workflow.xml
in Spark动作:
<spark-opts> --jars lib/*.jar</spark-opts>
但是这会导致另一个java.lang.NoClassDefFoundError
指向另一个缺失的类,所以我再次查找jar并复制,运行作业,同样的事情全部结束。看起来它需要依赖我的Hive lib中的许多jar。
我不明白的是当我使用jar在shell中使用spark-submit时,它运行正常,我可以选择并插入到我的Hive表中。只有当我使用Oozie时才会发生这种情况。看起来Spark在Oozie工作流作业中包含时不再能看到Hive库。有人能解释一下这是怎么发生的吗?
如何在Oozie路径中添加或引用必要的类/ jar?
我正在使用Cloudera Quickstart VM CDH 5.4.0,Spark 1.4.0,Oozie 4.1.0。
答案 0 :(得分:1)
避免Oozie中未找到ClassPath异常的更好方法是,在群集中安装Oozie SharedLib,并更新共享位置中的Hive / Pig罐子{Oozie共享位置中的某些时间现有罐子用于与不匹配产品罐。} HDFS://的hadoop:50070 /用户/ Oozie的/共享/ LIB / 一旦更新相同,请传递参数 “oozie.use.system.libpath = true”
这些将告知oozie从Hadoop共享位置读取Jars。
一旦你通过设置参数“真”提到共享位置,你就不需要在workflow.xml中逐一提及所有和每个jar
答案 1 :(得分:1)
通常是&#34;边缘节点&#34; (您可以连接的那个)在默认的CLASSPATH中预安装和引用了很多东西。 但是Hadoop&#34;工作节点&#34;可能是准系统,只预装了核心Hadoop库。
因此,您可以等待几年让Oozie在ShareLib中正确打包Spark依赖项,并使用&#34; blablah.system.libpath&#34;标志。
[EDIT] 如果基本Spark功能正常但您在Hive格式界面上失败,则指定ShareLibs的列表,包括&#34; HCatalog&#34; e.g。
action.sharelib.for.spark=spark,hcatalog
或者,您可以找到Spark实际使用的JAR和配置文件,将它们上传到HDFS,然后在&lt; file&gt;下的Oozie Action中逐个引用它们(所有这些都是一个接一个)。这样它们就可以在运行时下载到YARN容器的工作目录中。
[编辑] 也许ShareLibs包含JAR但不包含配置文件;那么你必须上传/下载的是一个有效的配置文件列表(Hive,Spark,等等)