使用临时凭证从 AWS 外部通过 Spark 从 s3 读取



我正在尝试通过IntelliJ从笔记本电脑从s3读取文件,以便我可以更轻松地开发我的Spark工作。

文本文件 RDD 代码在 EMR 集群中的齐柏林飞艇中工作,但当我在本地尝试时则不行。

在齐柏林飞艇中,我不需要进行任何 Spark 上下文设置,大概是因为它为我做了这件事,因为齐柏林飞艇实例位于 AWS 环境中。

我编写了代码来创建临时 AWS 凭证(使用我的 IAM 用户密钥(,以便我可以向 Spark 上下文提供会话令牌。访问密钥和私有密钥也来自临时凭证。

val sqlContext = sparkSession.sqlContext
        sqlContext.sparkContext.hadoopConfiguration
          .set("fs.s3a.impl", "org.apache.hadoop.fs.s3native.NativeS3FileSystem")
        sqlContext.sparkContext.hadoopConfiguration
          .set("fs.s3a.awsAccessKeyId", accessKeyId)
        sqlContext.sparkContext.hadoopConfiguration
          .set("fs.s3a.access.key", accessKeyId)
        sqlContext.sparkContext.hadoopConfiguration
          .set("fs.s3a.awsSecretAccessKey", secretAccessKey)
        sqlContext.sparkContext.hadoopConfiguration
          .set("fs.s3a.secret.key", secretAccessKey)
        sqlContext.sparkContext.hadoopConfiguration
          .set("fs.s3a.session.token", sessionToken)
        sqlContext.sparkContext.hadoopConfiguration.set("fs.s3a.credentialsType", "AssumeRole")
        sqlContext.sparkContext.hadoopConfiguration
          .set(
            "fs.s3a.stsAssumeRole.arn",
            "arn:aws:iam::1234:role/someRoleThatWasUsedInTheWorkingTempCredCode"
          )
        sqlContext.sparkContext.hadoopConfiguration.set(
          "fs.s3a.aws.credentials.provider",
          "org.apache.hadoop.fs.s3a.TemporaryAWSCredentialsProvider"
        )
sqlContext.sparkContext.textFile(
          "s3a://path/to/file/that/definitely/exists/3714bb50a146.gz"
        ).collect()

我期待一个包含文件中数据的数组,但我被拒绝了权限。

org.apache.hadoop.security.AccessControlException: Permission denied: s3n://path/to/file/that/definitely/exists/3714bb50a146.gz
    at org.apache.hadoop.fs.s3native.Jets3tNativeFileSystemStore.processException(Jets3tNativeFileSystemStore.java:449)
    at org.apache.hadoop.fs.s3native.Jets3tNativeFileSystemStore.processException(Jets3tNativeFileSystemStore.java:427)

两个问题:

1( 我正在做的事情是可能的吗(执行从本地读取 s3 的 Spark 作业(?

2(如果我正在做的事情是可能的,我的火花上下文设置代码是否有效?我觉得我缺少一个属性或使用错误的属性键。

掉关于fs.s3a.impl的那行。它所做的只是将"s3a"的默认映射更改为"现代、受支持、维护的 S3A 连接器",再到"旧的、过时的、不受支持的 S3N 连接器">

你不需要那行。编写火花应用程序的人总是这样做的事实只是迷信。Hadoop-common知道哪个文件系统类处理s3a URL,就像它知道谁处理"file"和"hdfs"一样。

最新更新