Java AWS EMR上的avro错误

Java AWS EMR上的avro错误,java,scala,hadoop,avro,amazon-emr,Java,Scala,Hadoop,Avro,Amazon Emr,我使用的是spark redshift(),它使用avro进行传输 读红移是可以的,而写我得到的 Caused by: java.lang.NoSuchMethodError: org.apache.avro.generic.GenericData.createDatumWriter(Lorg/apache/avro/Schema;)Lorg/apache/avro/io/DatumWriter 尝试使用Amazon EMR 4.1.0(Spark 1.5.0)和4.0.0(Spark 1.4

我使用的是spark redshift(),它使用avro进行传输

读红移是可以的,而写我得到的

Caused by: java.lang.NoSuchMethodError: org.apache.avro.generic.GenericData.createDatumWriter(Lorg/apache/avro/Schema;)Lorg/apache/avro/io/DatumWriter
尝试使用Amazon EMR 4.1.0(Spark 1.5.0)和4.0.0(Spark 1.4.1)。 不行

import org.apache.avro.generic.GenericData.createDatumWriter
或者,只是

import org.apache.avro.generic.GenericData
我使用的是scala shell 尝试下载其他几个avro mapred和avro JAR,尝试设置

{"classification":"mapred-site","properties":{"mapreduce.job.user.classpath.first":"true"}},{"classification":"spark-env","properties":{"spark.executor.userClassPathFirst":"true","spark.driver.userClassPathFirst":"true"}}
并将这些JAR添加到spark类路径。可能需要以某种方式调整Hadoop(EMR)


这会给任何人敲响警钟吗?

spark redshift
这里是维护人员


其他EMR用户在使用较新版本的
spark avro
库(取决于
spark redshift
)时也遇到类似错误。简而言之,问题似乎在于EMR的旧版本Avro优先于
spark Avro
要求的新版本。在,一个问题似乎与这里报告的异常情况相匹配,一位用户建议将Avro JAR与他们的应用程序代码一起嵌入:

这里是EMR的Jonathan。部分问题在于Hadoop依赖于AVRO1.7.4,完整的Hadoop类路径包含在EMR上的Spark路径中。这可能有助于我们将Hadoop的Avro依赖项升级到1.7.7,以便与Spark的Avro依赖项相匹配,尽管我有点担心这可能会破坏其他功能,但无论如何我都可以尝试一下


顺便说一句,我注意到您的示例EMR集群配置的一个问题是,您使用的是“spark env”配置分类,而“spark defaults”分类将是设置spark.{driver,executor}.userClassPathFirst的合适分类。不过,我不确定这本身就能解决您的问题。

仅供参考-Alex Nastetsky的解决方案

从主节点删除JAR

find / -name "*avro*jar" 2> /dev/null -print0 | xargs -0 -I file sudo rm file
从从属节点删除JAR

yarn node -list | sed 's/ .*//g' | tail -n +3 | sed 's/:.*//g' | xargs -I node ssh node "find / -name "*avro*jar" 2> /dev/null -print0 | xargs -0 -I file sudo rm file

按照Jonathan的建议正确设置configs也值得一试。

与Avro相关的EMR运行时冲突错误非常常见。 Avro被广泛使用,许多罐子都将其作为一种依赖性。 我在“NoSuchMethodError”或不同的Avro版本中看到了这个问题的不同方法的一些变体

我无法使用“spark.executor.userClassPathFirst”标志解决它,因为我得到了LinkageError

以下是为我解决冲突的解决方案:

  • 使用Intellij的依赖性分析器(Maven插件)将Avro从所有导致冲突的依赖性中排除
  • 设置EMR时,添加一个引导动作,该动作调用下载特定Avro JAR的bash脚本:

    #/bin/bash

    mkdir -p /home/hadoop/lib/
    cd /home/hadoop/lib/
    wget http://apache.spd.co.il/avro/avro-1.8.0/java/avro-1.8.0.jar
    
  • 设置EMR时,添加以下配置:

    [
    {"classification":"spark-defaults", "properties":{
    "spark.driver.extraLibraryPath":"/home/hadoop/lib/avro-1.8.0.jar:/usr/lib/hadoop/*:/usr/lib/hadoop/../hadoop-hdfs/*:/usr/lib/hadoop/../hadoop-mapreduce/*:/usr/lib/hadoop/../hadoop-yarn/*:/etc/hive/conf:/usr/lib/hadoop/../hadoop-lzo/lib/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*", 
    "spark.executor.extraClassPath":"/home/hadoop/lib/avro-1.8.0.jar:/usr/lib/hadoop/*:/usr/lib/hadoop/../hadoop-hdfs/*:/usr/lib/hadoop/../hadoop-mapreduce/*:/usr/lib/hadoop/../hadoop-yarn/*:/etc/hive/conf:/usr/lib/hadoop/../hadoop-lzo/lib/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*", 
    "spark.driver.extraClassPath":"/home/hadoop/lib/avro-1.8.0.jar:/usr/lib/hadoop/*:/usr/lib/hadoop/../hadoop-hdfs/*:/usr/lib/hadoop/../hadoop-mapreduce/*:/usr/lib/hadoop/../hadoop-yarn/*:/etc/hive/conf:/usr/lib/hadoop/../hadoop-lzo/lib/*:/usr/share/aws/emr/emrfs/conf:/usr/share/aws/emr/emrfs/lib/*:/usr/share/aws/emr/emrfs/auxlib/*"}, 
    "configurations":[]}
    ]
    

  • 如您所见,我必须将我的新库添加到现有库中。否则它不会工作。

    这很有帮助,但我现在使用的不是Java而是scala,scala shell。因此,试图找出如何使“spark.driver.userClassPathFirst”:“true”起作用。知道如何从EMR中删除旧的avro jar吗?不幸的是,我自己不是EMR用户。我建议将此问题发布在我链接的
    spark redshift
    线程上,因为其他用户可能知道如何执行此操作。谢谢,尽管spark redshift与redshift是同一个云,但它很难在EMR上工作,这并不好。这意味着人们很有可能在上使用spark redshiftEMR@devopslife:我同意。如果我们可以在
    spark redshift
    本身中进行修复,使其更易于在EMR上使用,那么我完全支持。然而,我担心这里的问题并不是特定于
    spark redshift
    ,而是红移提供的Avro依赖项的更一般问题的一个实例。在
    find
    子句中的第二个命令中存在轻微错误-应该在双引号中使用单引号。