使用Databricks Spark-Avro 3.2.0的NoSuchMethodError

时间:2017-04-03 04:14:53

标签: apache-spark avro databricks spark-avro

我有一个火花大师&工人在火花2.0.2和hadoop 2.7的Docker容器中运行。我试图通过运行

从另一个容器(同一网络)从pyspark提交作业
df = spark.read.json("/data/test.json")
df.write.format("com.databricks.spark.avro").save("/data/test.avro")

但是我收到了这个错误:

java.lang.NoSuchMethodError: org.apache.avro.generic.GenericData.createDatumWriter(Lorg/apache/avro/Schema;)Lorg/apache/avro/io/DatumWriter;

如果我以交互方式或使用spark-submit进行尝试,则没有任何区别。这些是我在spark中加载的包:

com.databricks#spark-avro_2.11;3.2.0 from central in [default]
com.thoughtworks.paranamer#paranamer;2.7 from central in [default]
org.apache.avro#avro;1.8.1 from central in [default]
org.apache.commons#commons-compress;1.8.1 from central in [default]
org.codehaus.jackson#jackson-core-asl;1.9.13 from central in [default]
org.codehaus.jackson#jackson-mapper-asl;1.9.13 from central in [default]
org.slf4j#slf4j-api;1.7.7 from central in [default]
org.tukaani#xz;1.5 from central in [default]
org.xerial.snappy#snappy-java;1.1.1.3 from central in [default]

spark-submit --version输出:

Welcome to
      ____              __
     / __/__  ___ _____/ /__
    _\ \/ _ \/ _ `/ __/  '_/
   /___/ .__/\_,_/_/ /_/\_\   version 2.0.2
      /_/

Branch 
Compiled by user jenkins on 2016-11-08T01:39:48Z
Revision 
Url 
Type --help for more information.

scala版本是2.11.8

我的pyspark命令:

PYSPARK_PYTHON=ipython /usr/spark-2.0.2/bin/pyspark --master spark://master:7077 --packages com.databricks:spark-avro_2.11:3.2.0,org.apache.avro:avro:1.8.1

我的spark-submit命令:

spark-submit script.py --master spark://master:7077 --packages com.databricks:spark-avro_2.11:3.2.0,org.apache.avro:avro:1.8.1

我已经读过here这可能是由于#34;正在使用的旧版本的avro"所以我尝试使用1.8.1,但我一直得到同样的错误。阅读avro工作正常。有什么帮助吗?

2 个答案:

答案 0 :(得分:2)

此错误的原因是默认情况下apo avro版本1.7.4包含在hadoop中,如果SPARK_DIST_CLASSPATH env变量在ivy2 jar之前包含hadoop common($HADOOP_HOME/share/common/lib/),可以使用错误的版本而不是spark-avro(> = 1.7.6)所需的版本并安装在ivy2中。

要检查是否是这种情况,请打开spark-shell并运行

sc.getClass().getResource("/org/apache/avro/generic/GenericData.class")

这应该告诉你类的位置如下:

java.net.URL = jar:file:/lib/ivy/jars/org.apache.avro_avro-1.7.6.jar!/org/apache/avro/generic/GenericData.class

如果该类指向$HADOOP_HOME/share/common/lib/,那么您必须在 {/ 1}} env变量中的hadoop之前简单地包含您的ivy2 jar

例如,在Dockerfile中

SPARK_DIST_CLASSPATH

注意: ENV SPARK_DIST_CLASSPATH="/home/root/.ivy2/*:$HADOOP_HOME/etc/hadoop/*:$HADOOP_HOME/share/hadoop/common/lib/*:$HADOOP_HOME/share/hadoop/common/*:$HADOOP_HOME/share/hadoop/hdfs/*:$HADOOP_HOME/share/hadoop/hdfs/lib/*:$HADOOP_HOME/share/hadoop/hdfs/*:$HADOOP_HOME/share/hadoop/yarn/lib/*:$HADOOP_HOME/share/hadoop/yarn/*:$HADOOP_HOME/share/hadoop/mapreduce/lib/*:$HADOOP_HOME/share/hadoop/mapreduce/*:$HADOOP_HOME/share/hadoop/tools/lib/*" 是ivy2 jars的默认位置,您可以通过在/home/root/.ivy2中设置spark.jars.ivy来操纵它,这可能是一个好主意

答案 1 :(得分:0)

之前我遇到过类似的问题。 尝试在 spark-submit

中使用 - jars {path to spark-avro_2.11-3.2.0.jar} 选项