(python)Spark .textFile(s3:// ...)使用有效凭据拒绝403

时间:2017-03-07 14:47:02

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

为了访问我的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但是火花正在窒息?

编辑:

使用s3a:// with

时出现同样的问题
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

的同样问题

1 个答案:

答案 0 :(得分:4)

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

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

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

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