【问题标题】:avro error on AWS EMRAWS EMR 上的 avro 错误
【发布时间】:2016-01-14 13:03:23
【问题描述】:

我正在使用 spark-redshift (https://github.com/databricks/spark-redshift),它使用 avro 进行传输。

从 Redshift 读取是可以的,而我正在写作

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"}}

并将这些 jars 添加到 spark 类路径中。可能需要以某种方式调整 Hadoop (EMR)。

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

【问题讨论】:

    标签: java scala hadoop avro amazon-emr


    【解决方案1】:

    spark-redshift 维护者在这里。

    其他 EMR 用户在使用较新版本的 spark-avro 库(spark-redshift 依赖于该库)时遇到了类似的错误。简而言之,问题似乎在于 EMR 的旧版本 Avro 优先于 spark-avro 要求的新版本。在https://github.com/databricks/spark-avro/issues/91,一个似乎与此处报告的异常相匹配的问题,一位用户建议将 Avro JAR 嵌入到他们的应用程序代码中:https://github.com/databricks/spark-avro/issues/91#issuecomment-142543149

    【讨论】:

    • 这很有帮助,但我现在使用的不是Java,而是scala,scala-shell。所以试图弄清楚如何使“spark.driver.userClassPathFirst”:“true”工作。知道如何从 EMR 中删除旧的 avro jar 吗?
    • 很遗憾,我自己不是 EMR 用户。我建议在我链接的spark-redshift 线程上发布这个问题,因为其他用户之一可能知道如何做到这一点。
    • 谢谢,虽然 spark-redshift 很难在 EMR 上工作,因为它与 Redshift 是同一个云。
    • 意味着人们很有可能在 EMR 上使用 spark-redshift
    • @devopslife:我同意。如果我们可以在spark-redshift 本身中进行修复以使其更易于在 EMR 上使用,那么我完全赞成。然而,我担心这里的问题并非特定于 spark-redshift,而是 Redshift 提供的 Avro 依赖项的更普遍问题的一个实例。
    【解决方案2】:

    这里是来自 EMR 的乔纳森。部分问题在于 Hadoop 依赖于 Avro 1.7.4,并且完整的 Hadoop 类路径包含在 EMR 上的 Spark 路径中。将 Hadoop 的 Avro 依赖升级到 1.7.7 可能对我们有所帮助,以便它与 Spark 的 Avro 依赖匹配,虽然我有点担心这可能会破坏其他东西,但无论如何我都可以尝试一下。

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

    【讨论】:

      【解决方案3】:

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

      从主节点删除 jars

      find / -name "*avro*jar" 2> /dev/null -print0 | xargs -0 -I file sudo rm file
      

      从从节点删除 jars

      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 的建议正确设置配置也值得一试。

      【讨论】:

      • find 子句中第二个命令的小错误 - 应在双引号内使用单引号。
      【解决方案4】:

      EMR 中与 Avro 相关的运行时冲突错误非常常见。 Avro 被广泛使用,许多 jar 都将它作为依赖项。 我在“NoSuchMethodError”或不同的 Avro 版本中看到了这个问题的几个变体。

      我无法使用 'spark.executor.userClassPathFirst' 标志解决它,因为我遇到了 LinkageError。

      这是为我解决冲突的解决方案:

      1. 使用 Intellij 的 Dependancy Analyzer(Maven 插件)将 Avro 从所有导致冲突的依赖项中排除。
      2. 在设置 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
        
      3. 设置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":[]}
        ]
        

      如您所见,我必须将我的新库与现有库一起添加。否则它不起作用。

      【讨论】:

        猜你喜欢
        • 2018-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多