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

时间:2019-04-04 11:19:19

标签: scala apache-spark hadoop amazon-s3 sbt

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

textFile RDD代码可在EMR集群内的Zeppelin中工作,但在本地尝试时不行。

在Zeppelin中,我不需要进行任何Spark上下文设置,大概是因为Zeppelin实例在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)如果我正在做的事情可行,那么我的Spark上下文设置代码是否有效?我觉得我缺少属性或使用了错误的属性密钥。

1 个答案:

答案 0 :(得分:1)

摆脱掉关于fs.s3a.impl的那一行。它所做的只是将默认映射从“ s3a”更改为“现代的,受支持的,维护的S3A连接器”,将其更改为“旧的,过时的,不受支持的S3N连接器”

您不需要该行。人们编写Spark应用程序总是这样做,这只是迷信。 Hadoop常见者知道哪个文件系统类处理s3a URL的方式与知道谁处理“文件”和“ hdfs”的方式相同