无法使用Spark 2.2

时间:2018-02-12 15:56:59

标签: apache-spark amazon-s3

我将大量数据上传到S3桶,我希望使用Spark和Zeppelin进行分析/可视化。然而,我仍然坚持从S3加载数据。

我做了一些阅读,以便将它们放在一起,并为我节省血腥的细节。我使用docker container p7hb/docker-spark作为Spark安装,我从S3读取数据的基本测试是from here

  1. 我启动容器以及其中的主进程和从进程。我可以通过查看在端口8080上公开的Spark Master WebUI来验证这项工作。此页面列出了工作人员并在标题下保留了所有失败尝试的日志"已完成的应用程序"。所有这些都处于州FINISHED

  2. 我在该容器内打开bash并执行以下操作:

    a)按照建议here导出环境变量AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY

    b)开始spark-shell。为了访问S3,似乎需要加载一些额外的包。通过SE浏览我特别发现this,它告诉我,我可以使用--packages参数来加载所述包。基本上我运行spark-shell --packages com.amazonaws:aws-java-sdk:1.7.15,org.apache.hadoop:hadoop-aws:2.7.5(,对于任意版本的组合)。

    c)我运行以下代码

    sc.hadoopConfiguration.set("fs.s3a.endpoint", "s3-eu-central-1.amazonaws.com") sc.hadoopConfiguration.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem") sc.hadoopConfiguration.set("com.amazonaws.services.s3.enableV4", "true")

    val sonnets=sc.textFile("s3a://my-bucket/my.file")

    val counts = sonnets.flatMap(line => line.split(" ")).map(word => (word, 1)).reduceByKey(_ + _)

  3. 然后我会收到各种不同的错误消息,具体取决于我在2b中选择的版本。

    我认为2a)没有问题,b / c如果我不提供错误消息,我会收到错误消息Unable to load AWS credentials from any provider in the chainThis is a known error new users seem to make.

    在尝试解决问题时,我会从herethere中为两个额外的包选择或多或少的随机版本。 SE上的某个地方我读到了hadoop-aws:2.7应该是正确的选择,因为Spark 2.2基于Hadoop 2.7。据说一个人需要使用aws-java-sdk:1.7和那个版本的hadoop-aws。

    不管!我尝试了以下组合

    • --packages com.amazonaws:aws-java-sdk:1.7.4,org.apache.hadoop:hadoop-aws:2.7.1,产生常见的错误请求400错误。 许多问题都可能导致该错误,我上面所述的尝试包含了我在此页面上能够找到的所有内容。上面的描述包含s3-eu-central-1.amazonaws.com作为端点,而其他地方使用s3.eu-central-1.amazonaws.com。根据{{​​3}},两个端点名称都应该起作用。我确实试过了。

    • --packages com.amazonaws:aws-java-sdk:1.7.15,org.apache.hadoop:hadoop-aws:2.7.5,这两种情况都是最新的微型版本,我收到错误消息java.lang.NoSuchMethodError: com.amazonaws.services.s3.transfer.TransferManager.<init>(Lcom/amazonaws/services/s3/AmazonS3;Ljava/util/concurrent/ThreadPoolExecuto r;)V

    • --packages com.amazonaws:aws-java-sdk:1.11.275,org.apache.hadoop:hadoop-aws:2.7.5,我也得到java.lang.NoSuchMethodError: com.amazonaws.services.s3.transfer.TransferManager.<init>(Lcom/amazonaws/services/s3/AmazonS3;Ljava/util/concurrent/ThreadPoolExecutor;)V

    • --packages com.amazonaws:aws-java-sdk:1.11.275,org.apache.hadoop:hadoop-aws:2.8.1,我得到java.lang.IllegalAccessError: tried to access method org.apache.hadoop.metrics2.lib.MutableCounterLong.<init>(Lorg/apache/hadoop/metrics2/MetricsInfo;J)V from class org.apache.hadoop.fs.s3a.S3AInstrumentation

    • --packages com.amazonaws:aws-java-sdk:1.11.275,org.apache.hadoop:hadoop-aws:2.8.3,我也得到java.lang.IllegalAccessError: tried to access method org.apache.hadoop.metrics2.lib.MutableCounterLong.<init>(Lorg/apache/hadoop/metrics2/MetricsInfo;J)V from class org.apache.hadoop.fs.s3a.S3AInstrumentation

    • --packages com.amazonaws:aws-java-sdk:1.8.12,org.apache.hadoop:hadoop-aws:2.8.3,我也得到java.lang.IllegalAccessError: tried to access method org.apache.hadoop.metrics2.lib.MutableCounterLong.<init>(Lorg/apache/hadoop/metrics2/MetricsInfo;J)V from class org.apache.hadoop.fs.s3a.S3AInstrumentation

    • --packages com.amazonaws:aws-java-sdk:1.11.275,org.apache.hadoop:hadoop-aws:2.9.0,我也得到java.lang.NoClassDefFoundError: org/apache/hadoop/fs/StorageStatistics

    而且,为了完整起见,当我不提供--packages参数时,我会java.lang.RuntimeException: java.lang.ClassNotFoundException: Class org.apache.hadoop.fs.s3a.S3AFileSystem not found

    目前似乎没有任何效果。然而,在这个主题上有很多Q / As,谁知道这样做的方式是什么。这都是本地模式,因此几乎没有其他错误来源。我访问S3的方法必定是错误的。它是如何正确完成的?

    编辑1:

    所以我又投入了一天,没有任何实际进展。据我所知,从Hadoop 2.6开始,Hadoop不再内置对S3的支持,但它通过其他库加载,这些库不是Hadoop的一部分,完全由它自己管理。除了所有杂乱,我最终想要的图书馆似乎是hadoop-aws。它有一个网页enter link description here,并带有我称之为权威信息的内容:

      

    hadoop-common和hadoop-aws的版本必须相同。

    关于此信息的重要一点是,hadoop-common实际上附带了Hadoop安装。每个Hadoop安装都有一个相应的jar文件,所以这是一个坚实的起点。我的容器有一个文件/usr/hadoop-2.7.3/share/hadoop/common/hadoop-common-2.7.3.jar,因此可以假设2.7.3是hadoop-aws所需的版本。

    之后它变得模糊不清。 Hadoop版本2.7.x在内部有一些内容,因此它们与aws-java-sdk的更新版本不兼容,hadoop-awshadoop-aws:2.7.3所需的库。互联网上充满了使用版本1.7.4 here的建议,但for example here建议使用版本1.7.14 for 2.7.x。

    所以我使用aws-java-sdk:1.7.xx进行了另一次运行,joda-time范围从4到14.无结果,我总是以错误400,错误请求结束。

    我的Hadoop安装${HADOOP_HOME}/share/hadoop/tools/lib 2.9.4。我看过问题是用Hadoop 2.8解决的。我想我会继续使用更新的版本构建我自己的docker容器。

    编辑2

    转移到Hadoop 2.8.3。它现在才有效。事实证明,你根本不必乱用JAR。 Hadoop附带了应该用于访问AWS S3的JAR。它们隐藏在{{1}}中,默认情况下不会添加到类路径中。我只是在该目录中加载JARS,如上所述执行我的代码,现在它可以正常工作。

1 个答案:

答案 0 :(得分:2)

如您所发现的那样,将AWS SDK JAR与其他任何东西混合搭配都是徒劳的。您需要构建AWS JARs Hadoop的版本,并且构建了Jackson AWS的版本。哦,不要尝试混合任何(不同的amazon- * JAR,不同的hadoop- * JAR,不同的jackson- * JARs);他们全都锁定同步。

对于Spark 2.2.0和Hadoop 2.7,使用AWS 1.7.4工件,并确保如果您使用的是Java 8,那么Joda时间是&gt; 2.8.0,如2.9.4。这可能导致400&#34;糟糕的身份验证问题&#34;。

否则,请尝试Troubleshooting S3A