use*_*682 5 amazon-s3 apache-spark
我将大量数据上传到我想要的 S3 存储桶,以便使用 Spark 和 Zeppelin 进行分析/可视化。然而,我仍然坚持从 S3 加载数据。
我做了一些阅读,以便将它们整合在一起,并免除我血腥的细节。我使用docker容器p7hb/docker-spark作为 Spark 安装,我从 S3 读取数据的基本测试来自这里:
我启动容器以及其中的主进程和从进程。我可以通过查看暴露在端口 8080 上的 Spark Master WebUI 来验证这项工作。此页面确实列出了工作人员并在标题“已完成的应用程序”下保留了我所有失败尝试的日志。所有这些都在状态中FINISHED。
我bash在该容器内打开一个并执行以下操作:
a)按照此处的建议导出环境变量AWS_ACCESS_KEY_ID和。AWS_SECRET_ACCESS_KEY
b) 开始spark-shell。为了访问 S3,似乎需要加载一些额外的包。在浏览 SE 时,我特别发现了这个,它教会了我,我可以使用该--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(_ + _)
然后我收到各种不同的错误消息,具体取决于我在 2b) 中选择的版本。
我想 2a)、b/c 没有任何问题,Unable to load AWS credentials from any provider in the chain如果我不提供这些信息,我会收到错误消息。这是新用户似乎会犯的一个已知错误。
在尝试解决这个问题时,我从这里和那里为两个额外的包选择了或多或少的随机版本。我在 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.comas 端点,而其他地方使用s3.eu-central-1.amazonaws.com. 根据在此处输入链接描述,两个端点名称都应该有效。我确实尝试了两者。
--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/A 太多了,谁知道这样做的方式是什么。这一切都在本地模式下,因此几乎没有其他错误来源。我访问 S3 的方法一定是错误的。它是如何正确完成的?
所以我又花了一天时间,没有任何实际进展。据我所知,从 Hadoop 2.6 开始,Hadoop 不再内置对 S3 的支持,而是通过其他库加载,这些库不是 Hadoop 的一部分,完全由自己管理。除了所有的杂乱之外,我最终想要的图书馆似乎是hadoop-aws. 它在这里有一个网页,其中包含我所说的权威信息:
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-aws。网上充斥着使用1.7.4版本的建议,例如这里,但其他评论 建议使用1.7.14版本用于2.7.x。
所以我使用hadoop-aws:2.7.3and进行了另一次运行aws-java-sdk:1.7.x,x范围从 4 到 14。没有任何结果,我总是以错误 400,错误请求结束。
我的 Hadoop 安装附带joda-time2.9.4。我读到问题已通过 Hadoop 2.8 解决。我想我会继续使用更新的版本构建我自己的 docker 容器。
移至 Hadoop 2.8.3。它现在才有效。事实证明,您甚至根本不必处理 JAR。Hadoop 附带了用于访问 AWS S3 的工作 JAR。${HADOOP_HOME}/share/hadoop/tools/lib默认情况下,它们隐藏在类路径中而不添加到类路径中。我只是将 JARS 加载到该目录中,如上所述执行我的代码,现在它可以工作了。
正如您所发现的,将 AWS SDK JAR 与其他任何东西混合和匹配是徒劳的。您需要构建 Hadoop 所使用的 AWS JAR 版本以及构建 AWS Jackson 的版本。哦,不要尝试混合任何(不同的 amazon-* JAR、不同的 hadoop-* JAR、不同的 jackson-* JAR);它们都处于锁定同步状态。
对于 Spark 2.2.0 和 Hadoop 2.7,请使用 AWS 1.7.4 工件,并确保如果您使用 Java 8,则 Joda 时间 > 2.8.0,例如 2.9.4。这可能会导致 400 个“错误的身份验证问题”。
否则,请尝试排除 S3A 故障
| 归档时间: |
|
| 查看次数: |
4032 次 |
| 最近记录: |