我已经在EC2上安装了spark 2.0 &我使用SparkSQL使用Scala从DB2检索记录。我想写S3,在那里我传递访问键到Spark上下文..以下是我的代码:
val df = sqlContext.read.format("jdbc").options(Map( "url" -> , "user" -> usernmae, "password" -> password, "dbtable" -> tablename, "driver" -> "com.ibm.db2.jcc.DB2Driver")).option("query", "SELECT * from tablename limit 10").load()
df.write.save("s3n://data-analytics/spark-db2/data.csv")
抛出以下异常:
org.apache.hadoop.fs.s3.S3Exception: org.jets3t.service.S3ServiceException: Service Error Message. -- ResponseCode: 403, ResponseStatus: Forbidden, XML Error Message: <?xml version="1.0" encoding="UTF-8"?><Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>1E77C38FA2DB34DA</RequestId><HostId>V4O9sdlbHwfXNFtoQ+Y1XYiPvIL2nTs2PIye5JBqiskMW60yDhHhnBoCHPDxLnTPFuzyKGh1gvM=</HostId></Error>
Caused by: org.jets3t.service.S3ServiceException: Service Error Message.
at org.jets3t.service.S3Service.putObject(S3Service.java:2358)
at org.apache.hadoop.fs.s3native.Jets3tNativeFileSystemStore.storeEmptyFile(Jets3tNativeFileSystemStore.java:162)
什么是确切的问题发生在这里,因为我传递访问密钥也Sparkcontext ??还有其他方法写入S3吗??
获得键之后,下面是如何在s3n上的scala/spark2中写入s3的方法。
spark.sparkContext.hadoopConfiguration.set("fs.s3n.awsAccessKeyId", "[access key]")
spark.sparkContext.hadoopConfiguration.set("fs.s3n.awsSecretAccessKey", "[secret key]")
spark.sparkContext.hadoopConfiguration.set("fs.s3n.impl", "org.apache.hadoop.fs.s3native.NativeS3FileSystem")
df.write
.mode("overwrite")
.parquet("s3n://bucket/folder/parquet/myFile")
这是如何使用s3a,这是首选的。
spark.sparkContext.hadoopConfiguration.set("fs.s3a.access.key", "[access key]")
spark.sparkContext.hadoopConfiguration.set("fs.s3a.secret.key", "[secret key]")
spark.sparkContext.hadoopConfiguration.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
df.write
.mode("overwrite")
.parquet("s3a://bucket/folder/parquet/myFile")
查看这篇文章了解s3, s3n和s3a之间的区别
当您在AWS上创建EC2实例或EMR集群时,您可以在创建过程中选择将IAM角色附加到该实例或集群。
默认情况下,EC2实例不允许连接S3。您需要创建一个角色,并首先将其附加到实例。
附加IAM角色的目的是,IAM角色可以被授予使用各种其他AWS服务的权限,而无需在该实例上安装物理凭据。如果有一个访问拒绝错误,我假设实例没有一个IAM角色附加到它,没有足够的权限来写S3。
下面是如何创建一个新的IAM角色:
- 导航到AWS身份和访问管理(IAM)页面。
- 单击Roles,创建一个新的角色。
- 在搜索栏中搜索S3,然后选择S3FullAccess(…)或者类似的东西,我一时想不起来了)
- 添加你想要这个角色拥有的任何其他服务。
- 保存它。
对于常规的旧单个EC2实例,单击创建新实例:
- ,在实例创建步骤的页面中,在选择VPC和子网的地方,有一个IAM角色选择框,单击它并选择您新创建的角色。
- 继续并像之前一样创建实例。现在该实例拥有了向S3写入的权限。瞧!
对于EMR集群:
- 创建EMR集群,然后导航到GUI页面,在这里您可以看到新集群的详细信息。找到右边写着EMR Role的区域,然后在IAM区域中找到该角色,并通过添加S3完全权限对其进行编辑。
你可以试试这个
df.write.mode("append").format("csv").save("path/to/s3/bucket");