为什么elasticsearch-spark 5.5.0在提交给YARN集群时会因AbstractMethodError而失败?

时间:2017-08-04 09:09:39

标签: apache-spark elasticsearch apache-spark-sql apache-spark-2.2

我写了一个火花作业,其主要目标是写入es,并提交它,问题是当我将它提交到spark集群时,spark返回

  

[错误] [org.apache.spark.deploy.yarn.ApplicationMaster]用户类抛出异常:java.lang.AbstractMethodError:org.elasticsearch.spark.sql.DefaultSource.createRelation(Lorg / apache / spark / sql / SQLContext; Lorg /阿帕奇/火花/ SQL / SaveMode; Lscala /收集/不变/地图; Lorg /阿帕奇/火花/ SQL /数据集;)Lorg /阿帕奇/火花/ SQL /来源/ 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 /火花/ SQL /数据集;)Lorg /阿帕奇/火花/ SQL /来源/ 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.execution.command.ExecutedCommandExec.sideEffectResult $ lzycompute(commands.scala:58)       在org.apache.spark.sql.execution.command.ExecutedCommandExec.sideEffectResult(commands.scala:56)       在org.apache.spark.sql.execution.command.ExecutedCommandExec.doExecute(commands.scala:74)       在org.apache.spark.sql.execution.SparkPlan $$ anonfun $执行$ 1.apply(SparkPlan.scala:117)这里

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

1 个答案:

答案 0 :(得分: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)

这将为您提供问题“出生”的确切位置(请参见that line):

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。数据源确实是CreatableRelationProvider

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

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

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

我很困惑,但希望答案能对造成这种情况的原因有所启发。