【问题标题】:Spark job fails due to java.lang.NoSuchMethodException: org.apache.hadoop.hive.ql.metadata.Hive.loadDynamicPartitions由于 java.lang.NoSuchMethodException,Spark 作业失败:org.apache.hadoop.hive.ql.metadata.Hive.loadDynamicPartitions
【发布时间】:2016-11-16 16:43:49
【问题描述】:

由于以下错误,我无法通过 spark-submit 运行 spark 作业:

16/11/16 11:41:12 ERROR yarn.ApplicationMaster: User class threw exception: java.lang.NoSuchMethodException: org.apache.hadoop.hive.ql.metadata.Hive.loadDynamicPartitions(org.apache.hadoop.fs.Path, java.lang.String, java.util.Map, boolean, int, boolean, boolean, boolean)
java.lang.NoSuchMethodException: org.apache.hadoop.hive.ql.metadata.Hive.loadDynamicPartitions(org.apache.hadoop.fs.Path, java.lang.String, java.util.Map, boolean, int, boolean, boolean, boolean)
at java.lang.Class.getMethod(Class.java:1786)
at org.apache.spark.sql.hive.client.Shim.findMethod(HiveShim.scala:114)
at org.apache.spark.sql.hive.client.Shim_v0_14.loadDynamicPartitionsMethod$lzycompute(HiveShim.scala:404)
at org.apache.spark.sql.hive.client.Shim_v0_14.loadDynamicPartitionsMethod(HiveShim.scala:403)
at org.apache.spark.sql.hive.client.Shim_v0_14.loadDynamicPartitions(HiveShim.scala:455)
at org.apache.spark.sql.hive.client.ClientWrapper$$anonfun$loadDynamicPartitions$1.apply$mcV$sp(ClientWrapper.scala:562)
at org.apache.spark.sql.hive.client.ClientWrapper$$anonfun$loadDynamicPartitions$1.apply(ClientWrapper.scala:562)
at org.apache.spark.sql.hive.client.ClientWrapper$$anonfun$loadDynamicPartitions$1.apply(ClientWrapper.scala:562)
at org.apache.spark.sql.hive.client.ClientWrapper$$anonfun$withHiveState$1.apply(ClientWrapper.scala:281)
at org.apache.spark.sql.hive.client.ClientWrapper.liftedTree1$1(ClientWrapper.scala:228)
at org.apache.spark.sql.hive.client.ClientWrapper.retryLocked(ClientWrapper.scala:227)
at org.apache.spark.sql.hive.client.ClientWrapper.withHiveState(ClientWrapper.scala:270)
...

我将 spark 1.6.0 与 scala 2.10、hive 1.1.0 一起使用,平台是 CDH 5.7.1,具有相同版本的 spark 和 hive。 在类路径上传递给 spark 作业的 hive-exec 是 hive-exec-1.1.0-cdh5.7.1.jar。这个 jar 有一个类org.apache.hadoop.hive.ql.metadata.Hive,我可以看到它有以下方法:

public java.util.Map<java.util.Map<java.lang.String, java.lang.String>, org.apache.hadoop.hive.ql.metadata.Partition> loadDynamicPartitions(org.apache.hadoop.fs.Path, java.lang.String, java.util.Map<java.lang.String, java.lang.String>, boolean, int, boolean, boolean, boolean) throws org.apache.hadoop.hive.ql.metadata.HiveException;

这与我正在使用的库 spark-hive_2.10-1.6.0.jar 附带的 org.apache.spark.sql.hive.client.ClientWrapper 类上的不同,该类中相同方法的签名是使用该类org.apache.spark.sql.hive.client.HiveShim 用这个方法:

private lazy val loadDynamicPartitionsMethod =
findMethod(
  classOf[Hive],
  "loadDynamicPartitions",
  classOf[Path],
  classOf[String],
  classOf[JMap[String, String]],
  JBoolean.TYPE,
  JInteger.TYPE,
  JBoolean.TYPE,
  JBoolean.TYPE)

我还检查了 hive-exec jar 的历史记录,似乎 org.apache.hadoop.hive.ql.metadata.Hive 类的签名在版本 1.0.0 之后发生了更改。 我是 Spark 的新手,但在我看来 spark-hive 库使用了 Hive 的旧实现(我可以在 jar 内的 META-INF/DEPENDENCIES 文件中看到声明了对 org.spark-project.hive 的依赖: hive-exec:jar:1.2.1.spark)。 有谁知道如何设置 spark 作业以使用正确的 hive 库?

【问题讨论】:

  • 您找到解决方案了吗?

标签: apache-spark hive cloudera


【解决方案1】:

确保您已设置以下设置

SET hive.exec.dynamic.partition=true; 
SET hive.exec.max.dynamic.partitions=2048
SET hive.exec.dynamic.partition.mode=nonstrict;

在 Spark 中,您可以在 hive 上下文中设置如下

hiveCtx.setConf("hive.exec.dynamic.partition","true")
hiveCtx.setConf("hive.exec.max.dynamic.partitions","2048")
hiveCtx.setConf("hive.exec.dynamic.partition.mode", "nonstrict")

如果问题仍然存在,我猜这意味着您使用的 spark 版本与您尝试运行 spark-submit 的环境不匹配...您可以尝试在 spark-shell 中运行您的程序,如果它可以工作,然后尝试将 spark 版本与环境设置对齐。

你可以像下面这样设置对你的 sbt 或 pom 的依赖

libraryDependencies += "org.apache.spark" % "spark-core_2.10" % "1.6.3"
libraryDependencies += "org.apache.spark" % "spark-sql_2.10" % "1.6.3"
libraryDependencies += "org.apache.spark" % "spark-hive_2.10" % "1.6.3"
libraryDependencies += "org.apache.hive" % "hive-exec" % "1.1.0"

请参考 https://mvnrepository.com/artifact/org.apache.spark

您可以使用以下命令获取环境设置 SPARK_PRINT_LAUNCH_COMMAND=true spark-shell

另一种方法是使用 spark partition by 来保存数据

    dataframe.write.mode("overwrite").partitionBy("col1", "col2").json("//path")

【讨论】:

  • 我有这个问题,你在哪里指定: libraryDependencies += "org.apache.spark" % "spark-core_2.10" % "1.6.3" libraryDependencies += "org.apache.火花”%“火花-sql_2.10”%“1.6.3”库依赖+=“org.apache.spark”%“火花-hive_2.10”%“1.6.3”库依赖+=“org.apache.hive” % "hive-exec" % "1.1.0" ?
  • 在 sbt 或 maven 中
  • @LuisLeal 是 sbt,但你可以在 maven 中定义相同
  • 感谢您的回答,您能否提供一些详细信息,例如要修改哪个配置文件,或者启动 spark 会话时是否在命令行参数?
猜你喜欢
  • 2017-11-24
  • 2019-01-18
  • 2014-06-29
  • 2016-10-10
  • 2017-11-23
  • 1970-01-01
  • 2019-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多