1

我写了一个spark job,主要目标是写入es,然后提交,问题是当我提交到spark集群时,spark返回

[错误] [org.apache.spark.deploy.yarn.ApplicationMaster] 用户类抛出异常:java.lang.AbstractMethodError: org.elasticsearch.spark.sql.DefaultSource.createRelation(Lorg/apache/spark/sql/SQLContext;Lorg /apache/spark/sql/SaveMode;Lscala/collection/immutable/Map;Lorg/apache/spark/sql/Dataset;)Lorg/apache/spark/sql/sources/BaseRelation; java.lang.AbstractMethodError: org.elasticsearch.spark.sql.DefaultSource.createRelation(Lorg/apache/spark/sql/SQLContext;Lorg/apache/spark/sql/SaveMode;Lscala/collection/immutable/Map;Lorg/apache/ spark/sql/Dataset;)Lorg/apache/spark/sql/sources/BaseRelation; 在 org.apache.spark.sql.execution.datasources.DataSource.write(DataSource.scala:472) 在 org.apache.spark.sql.execution.datasources.SaveIntoDataSourceCommand.run(SaveIntoDataSourceCommand.scala:48) 在 org.apache .spark.sql.执行。

但是,如果我使用 local[2] 提交我的工作,那么工作就很好了。奇怪,两个jar的环境是一样的。我用的是elasticsearch-spark20_2.11_5.5.0和spark2.2

4

1 回答 1

1

看来您面临 Spark 版本不匹配的问题,即您使用elasticsearch-spark20_2.11_5.5.0(名称中的注释spark20)和 Spark 2.2。

引用java.lang.AbstractMethodError的 javadoc :

当应用程序尝试调用抽象方法时抛出。通常,这个错误会被编译器捕获;如果自上次编译当前执行的方法以来某些类的定义发生了不兼容的更改,则此错误只会在运行时发生。

这几乎解释了您的体验(注意以“此错误只能在运行时发生”开头的部分)。

深入挖掘,堆栈跟踪中的这一行给了我您使用的 Spark 的确切版本,即 Spark 2.2.0。

org.apache.spark.sql.execution.datasources.DataSource.write(DataSource.scala:472)

这为您提供了问题“诞生”的确切位置(请参阅该行):

dataSource.createRelation(sparkSession.sqlContext, mode, caseInsensitiveOptions, data)

这与堆栈跟踪中的最顶层行匹配:

java.lang.AbstractMethodError: org.elasticsearch.spark.sql.DefaultSource.createRelation(Lorg/apache/spark/sql/SQLContext;Lorg/apache/spark/sql/SaveMode;Lscala/collection/immutable/Map;Lorg/apache/ spark/sql/Dataset;)Lorg/apache/spark/sql/sources/BaseRelation; java.lang.AbstractMethodError: org.elasticsearch.spark.sql.DefaultSource.createRelation(Lorg/apache/spark/sql/SQLContext;Lorg/apache/spark/sql/SaveMode;Lscala/collection/immutable/Map;Lorg/apache/ spark/sql/Dataset;)Lorg/apache/spark/sql/sources/BaseRelation

看起来elasticsearch-spark20_2.11_5.5.0连接器是一个CreatableRelationProvider,但不知何故它没有实现该方法。既然 Spark 2.0 已经有了这个接口,这怎么可能?!让我们找出并查看elasticsearch-spark20_2.11_5.5.0.

从堆栈跟踪您知道 ES 实现是org.elasticsearch.spark.sql.DefaultSource。数据源确实是一个CreateableRelationProvider

private[sql] class DefaultSource ... with CreatableRelationProvider  {

它确实覆盖了所需的createRelation方法(否则,由于接口从 1.3 开始就存在,因此无法编译它!)

方法和堆栈跟踪之间的唯一变化是data: DataFrame(在连接器和接口中)与Lorg/apache/spark/sql/Dataset;堆栈跟踪。这就引出了关于 Spark 应用程序中代码的问题,或者您将 Spark 应用程序提交到 YARN 集群的方式可能有问题(并且您确实将 Spark 应用程序提交到 YARN 集群,不是吗?

我很困惑,但希望答案能阐明可能导致它的原因。

于 2018-07-18T08:50:25.283 回答