为了访问我的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
的同样问题答案 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之间的时钟偏差。