8

为了访问我的 S3 存储桶,我导出了我的信用

export AWS_SECRET_ACCESS_KEY=
export AWS_ACCESSS_ACCESS_KEY=

我可以通过做来验证一切正常

aws s3 ls mybucket

我还可以用 boto3 验证它在 python 中是否有效

resource = boto3.resource("s3", region_name="us-east-1")
resource.Object("mybucket", "text/text.py") \
            .put(Body=open("text.py", "rb"),ContentType="text/x-py")

这有效,我可以看到存储桶中的文件。

但是,当我用火花这样做时:

spark_context = SparkContext()
sql_context = SQLContext(spark_context)
spark_context.textFile("s3://mybucket/my/path/*)

我得到一个不错的

> Caused by: org.jets3t.service.S3ServiceException: Service Error
> Message. -- ResponseCode: 403, ResponseStatus: Forbidden, XML Error
> Message: <?xml version="1.0"
> encoding="UTF-8"?><Error><Code>InvalidAccessKeyId</Code><Message>The
> AWS Access Key Id you provided does not exist in our
> records.</Message><AWSAccessKeyId>[MY_ACCESS_KEY]</AWSAccessKeyId><RequestId>XXXXX</RequestId><HostId>xxxxxxx</HostId></Error>

这就是我在本地提交工作的方式

spark-submit --packages com.amazonaws:aws-java-sdk-pom:1.11.98,org.apache.hadoop:hadoop-aws:2.7.3 test.py

为什么它可以与命令行 + boto3 一起使用,但 spark 是阻塞的?

编辑:

使用 s3a:// 同样的问题

hadoopConf = spark_context._jsc.hadoopConfiguration()
hadoopConf.set("fs.s3a.access.key", "xxxx")
hadoopConf.set("fs.s3a.secret.key", "xxxxxxx")
hadoopConf.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")

和使用 aws-sdk 1.7.4 和 hadoop 2.7.2 的相同问题

4

1 回答 1

7

Spark 会自动将您的 AWS 凭证复制到 s3n 和 s3a 密钥。Apache Spark 版本不涉及 s3:// URL,因为在 Apache Hadoop 中,s3:// 架构与原始的、现已弃用的 s3 客户端相关联,该客户端与其他所有客户端都不兼容。

在 Amazon EMR 上,s3:// 绑定到 amazon EMR S3;EC2 虚拟机将自动为执行者提供秘密。所以我认为它不会影响 env var 传播机制。也可能是它如何设置身份验证链,您无法覆盖 EC2/IAM 数据。

如果您尝试与 S3 通信并且您没有在 EMR VM 中运行,那么您可能正在使用带有 Apache Hadoop JAR 的 Apache Spark,而不是 EMR 版本。在那个世界中,使用带有 s3a:// 的 URL 来获取最新的 S3 客户端库

如果这不起作用,请查看apache 文档的故障排除部分。那里有一个关于“403”的部分,包括推荐的故障排除步骤。这可能是由于类路径/JVM 版本问题以及凭证问题,甚至是客户端和 AWS 之间的时钟偏差。

于 2017-03-07T16:06:24.203 回答