【问题标题】:(python) Spark .textFile(s3://...) access denied 403 with valid credentials(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

【问题讨论】:

  • 我认为它也适用于导出 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我想我找到了问题我已经为它创建了一个新帖子stackoverflow.com/questions/42669246/…

标签: apache-spark amazon-s3 pyspark http-status-code-403 access-keys


【解决方案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 我想我找到了问题,我已经为它创建了一个新帖子stackoverflow.com/questions/42669246/…
猜你喜欢
  • 2018-01-11
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 2013-07-26
  • 2015-08-08
  • 1970-01-01
  • 2018-04-18
  • 2014-03-10
相关资源
最近更新 更多