PySpark使用IAM角色访问S3

时间:2016-03-22 21:36:16

标签: python amazon-web-services amazon-s3 pyspark amazon-iam

我想知道PySpark是否支持使用IAM角色进行S3访问。具体来说,我有一个业务约束,我必须承担AWS角色才能访问给定的存储桶。这在使用boto时是很好的(因为它是API的一部分),但我无法找到关于PySpark是否支持开箱即用的明确答案。

理想情况下,我希望能够在本地以独立模式运行时担任角色,并将我的SparkContext指向该s3路径。我已经看到非IAM调用通常遵循:

spark_conf = SparkConf().setMaster('local[*]').setAppName('MyApp')
sc = SparkContext(conf=spark_conf)
rdd = sc.textFile('s3://<MY-ID>:<MY-KEY>@some-bucket/some-key')

是否存在提供IAM信息的类似内容? :

rdd = sc.textFile('s3://<MY-ID>:<MY-KEY>:<MY-SESSION>@some-bucket/some-key')

rdd = sc.textFile('s3://<ROLE-ARN>:<ROLE-SESSION-NAME>@some-bucket/some-key')

如果没有,使用IAM信用卡的最佳做法是什么?它甚至可能吗?

我正在使用Python 1.7和PySpark 1.6.0

谢谢!

5 个答案:

答案 0 :(得分:3)

访问s3的IAM角色仅由 s3a 支持,因为它使用的是AWS SDK。

您需要将hadoop-aws JAR和aws-java-sdk JAR(及其第三方Jars)放入CLASSPATH。

hadoop-aws链接。

aws-java-sdk链接。

然后在core-site.xml

中设置此项
<property>
    <name>fs.s3.impl</name>
    <value>org.apache.hadoop.fs.s3a.S3AFileSystem</value>
</property>
<property>
    <name>fs.s3a.impl</name>
    <value>org.apache.hadoop.fs.s3a.S3AFileSystem</value>
</property>

答案 1 :(得分:1)

IAM支持Spark对S3中的文件进行基于角色的访问,您只需谨慎配置即可。具体来说,您需要:

  • aws-java-sdkhadoop-aws的兼容版本。这是quite brittle,因此仅特定的组合有效。
  • 您必须使用S3AFileSystem,而不是NativeS3FileSystem。前者允许基于角色的访问,而后者仅允许用户凭据。

这对我有用:

导入操作系统

import pyspark
from pyspark import SparkContext
from pyspark.sql import SparkSession

os.environ['PYSPARK_SUBMIT_ARGS'] = '--packages com.amazonaws:aws-java-sdk:1.7.4,org.apache.hadoop:hadoop-aws:2.7.1 pyspark-shell'

sc = SparkContext.getOrCreate()

hadoopConf = sc._jsc.hadoopConfiguration()
hadoopConf.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")

spark = SparkSession(sc)

df = spark.read.csv("s3a://mybucket/spark/iris/",header=True)
df.show()

aws-java-sdk:1.7.4hadoop-aws:2.7.1的特定组合神奇地使它起作用。关于s3a访问here

的故障排除,有很好的指导

特别注意

  

随意更改hadoop-和aws- JAR,希望使问题“消失”或获得所需功能的使用,不会导致您想要的结果。

     

提示:您可以使用mvnrepository来确定ASF发布的特定hadoop-aws JAR的依赖版本要求。

这里是useful post,其中包含更多信息。

关于Java库之间兼容性的更多useful information

我正试图使它在jupyter pyspark notebook中起作用。请注意,aws-hadoop版本必须与Dockerfile中的hadoop安装匹配,即here

答案 2 :(得分:0)

你可以在Locally reading S3 files through Spark (or better: pyspark)中尝试这种方法。

然而,我在Bash中设置环境变量(AWS_ACCESS_KEY_ID等)的运气更好...... pyspark会自动为你的会话选择这些变量。

答案 3 :(得分:0)

经过更多的研究,我确信这一点尚未得到证实here

其他人建议采用更加手动的方法(参见this blog post)建议使用boto列出s3键,然后使用Spark并行化该列表来读取每个对象。

这里的问题(我还没看到他们自己如何绕过它)是从桶中列表返回的s3对象不可序列化/可拾取(请记住:建议给出这些对象)让工人通过map或flatMap读取独立的进程)。进一步解决的问题是boto s3客户端本身不可序列化(在我看来这是合理的)。

我们剩下的是唯一选择在每个文件中重新创建假定角色s3客户端 ,这在某个点之后不是最佳或可行的。

如果有人发现这种推理或替代解决方案/方法存在任何缺陷,我很乐意听到。

答案 4 :(得分:0)

Hadoop 2.8+的s3a连接器通过新的凭据提供程序支持IAM角色;不在Hadoop 2.7版本中 要使用它,您需要更改凭证提供者。 fs.s3a.aws.credentials.provider = org.apache.hadoop.fs.s3a.TemporaryAWSCredentialsProvider fs.s3a.access.key = <your access key> fs.s3a.secret.key = <session secret> fs.s3a.session.token = <session token> Hadoop 2.7中的功能(默认情况下已启用)是AWS_环境变量的选择。

如果您将AWS env vars设置为在本地系统和远程系统上进行会话登录,则应该将其选中。

我知道这很痛苦,但是就Hadoop团队而言,Hadoop 2.7将于2016年中期发布,自那时以来我们已经做了很多工作,我们不会回溯