(python) Spark .textFile(s3://...) access denied 403 with valid credentials

Posted

技术标签:

【中文标题】(python) Spark .textFile(s3://...) access denied 403 with valid credentials【英文标题】: 【发布时间】:2017-07-27 20:01:46 【问题描述】:

为了访问我的 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 执行此操作时:

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

【问题讨论】:

读过这个吗? cloudera.com/documentation/enterprise/latest/topics/… 我认为它也适用于导出 AWS_SECRET_ACCESS_KEY 和 AWS_ACCESS_KEY。创建该凭据文件真的有必要吗?如您所见,Spark 正确地从 env 变量中获取 AWS_ACCESS_KEY 但由于原因无法进行身份验证? Spark 已分发。因为您在一个执行程序中有 ENV 变量并不意味着其他执行程序也有它。您应该使用SparkConf 设置值 hadoopConf = spark_context._jsc.hadoopConfiguration() hadoopConf.set("fs.s3.awsAccessKeyId", "xxxxx") hadoopConf.set("fs.s3.awsSecretAccessKey", "xxxxxx) 和使用 SparkConf 设置时同样的错误 @cricket_007我想我找到了问题我已经为它创建了一个新帖子***.com/questions/42669246/… 【参考方案1】:

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 虚拟机中运行,那么您可能正在使用带有 Apache Hadoop JAR 的 Apache Spark,而不是 EMR 版本。在那个世界中,使用带有 s3a:// 的 URL 来获取最新的 S3 客户端库

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

【讨论】:

对不起,我忘了在 originap 帖子中提到它,但我没有在 EMR 中运行它(它在那里工作)。我在本地运行它。我将尝试使用 s3a:// 相同但错误略有不同:错误消息:状态代码:403,AWS 服务:Amazon S3,AWS 请求 ID:XXXX,AWS 错误代码:null,AWS 错误消息:禁止 好的,S3A 是 ASF 代码。除了身份验证问题外,它还可能受到 joda-time 和 JVM 版本不兼容的影响。我将使用相关文档的链接编辑我的答案 感谢您的链接。我的时钟在正确的时间,我使用 java 7 并且按照原始帖子中的说明,我的凭据是正确的,因为 aws s3 命​​令和 boto3 都可以毫无问题地读取存储桶 @Seteve 我想我找到了问题,我已经为它创建了一个新帖子***.com/questions/42669246/…

以上是关于(python) Spark .textFile(s3://...) access denied 403 with valid credentials的主要内容,如果未能解决你的问题,请参考以下文章

Spark源码解读--spark.textFile()读取流程

spark textFile 困惑与解释

spark sc.textFile() 指定换行符

Spark 使用 sc.textFile ("s3n://...) 从 S3 读取文件

spark配置

Spark学习:RDD编程