emr spark无法将Dataframe保存到s3

mbzjlibv  于 2021-06-02  发布在  Hadoop
关注(0)|答案(2)|浏览(524)

我用的是 RunJobFlow 命令启动一个spark emr集群。此命令设置 JobFlowRole 一个有政策的iam角色 AmazonElasticMapReduceforEC2Role 以及 AmazonRedshiftReadOnlyAccess . 第一个策略包含允许所有s3权限的操作。
当ec2示例启动时,它们承担这个iam角色,并通过sts生成临时凭证。
我要做的第一件事是使用 com.databricks.spark.redshift 格式化并使用相同的iam角色从redshift卸载数据,就像我对emr所做的那样 JobFlowRole .
据我所知,这是一个 UNLOAD 命令redshift到我指定的s3 bucket中。spark然后将新卸载的数据加载到Dataframe中。我使用推荐的 s3n:// 协议 tempdir 选项。
这个命令非常有效,它总是成功地将数据加载到Dataframe中。
然后我运行一些转换并尝试将Dataframe保存在 csv 格式化为相同的s3 bucket红移 Unloaded 进入。
但是,当我尝试这样做时,它抛出以下错误 java.lang.IllegalArgumentException: AWS Access Key ID and Secret Access Key must be specified as the username or password (respectively) of a s3n URL, or by setting the fs.s3n.awsAccessKeyId or fs.s3n.awsSecretAccessKey properties (respectively) 可以。所以我不知道为什么会发生这种情况,但是我试图通过设置推荐的hadoop配置参数来解决这个问题。然后我用 DefaultAWSCredentialsProviderChain 加载 AWSAccessKeyID 以及 AWSSecretKey 并通过 spark.sparkContext.hadoopConfiguration.set("fs.s3n.awsAccessKeyId", <CREDENTIALS_ACCESS_KEY>) spark.sparkContext.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey", <CREDENTIALS_SECRET_ACCESS_KEY>) 当我再次运行它时,它会抛出以下错误: java.io.IOException: com.amazon.ws.emr.hadoop.fs.shaded.com.amazonaws.services.s3.model.AmazonS3Exception: The AWS Access Key Id you provided does not exist in our records. (Service: Amazon S3; Status Code: 403; Error Code: InvalidAccessKeyId; 可以。所以那没用。然后我删除了hadoop配置的设置,并通过在s3url中硬编码了iam用户的凭证 s3n://ACCESS_KEY:SECRET_KEY@BUCKET/KEY 当我运行这个时,它会抛出以下错误: java.lang.IllegalArgumentException: Bucket name should be between 3 and 63 characters long 所以它试图制造一个桶。。这绝对不是我们想要它做的。
我真的被困在这一个,并将非常感谢任何帮助在这里!当我在本地运行它时,它工作正常,但在emr上完全失败。

zujrkrfu

zujrkrfu1#

问题如下:
ec2示例在emr引导阶段生成临时凭证
当我询问红移时,我通过了考试 aws_iam_role 到数据块驱动程序。然后,驱动程序为同一iam角色重新生成临时凭据。这使ec2示例生成的凭据无效。
然后,我尝试使用旧凭据(以及存储在示例元数据中的凭据)上载到s3
它失败了,因为它试图使用过期的凭据。
解决方案是通过 aws_iam_role 并替换为以下内容: val credentials = EC2MetadataUtils.getIAMSecurityCredentials ... .option("temporary_aws_access_key_id", credentials.get(IAM_ROLE).accessKeyId) .option("temporary_aws_secret_access_key", credentials.get(IAM_ROLE).secretAccessKey) .option("temporary_aws_session_token", credentials.get(IAM_ROLE).token)

qgelzfjb

qgelzfjb2#

在amazonemr上,尝试使用前缀s3://来引用s3中的对象。
说来话长。

相关问题