Spark Scala S3 存储:权限被拒绝

Posted

技术标签:

【中文标题】Spark Scala S3 存储:权限被拒绝【英文标题】:Spark Scala S3 storage: permission denied 【发布时间】:2018-10-11 10:16:36 【问题描述】:

我在 Internet 上阅读了很多关于如何让 Spark 与 S3 一起工作的主题,但仍然没有任何工作正常。 我已经下载了:Spark 2.3.2 with hadoop 2.7 and above。

我只将一些库从 Hadoop 2.7.7(与 Spark/Hadoop 版本匹配)复制到 Spark jars 文件夹:

hadoop-aws-2.7.7.jar hadoop-auth-2.7.7.jar aws-java-sdk-1.7.4.jar

我仍然不能使用 S3N 和 S3A 来让 spark 读取我的文件:

对于 S3A,我有这个例外:

sc.hadoopConfiguration.set("fs.s3a.access.key","myaccesskey")
sc.hadoopConfiguration.set("fs.s3a.secret.key","mysecretkey")
val file = sc.textFile("s3a://my.domain:8080/test_bucket/test_file.txt")
com.amazonaws.services.s3.model.AmazonS3Exception: Status Code: 403, AWS Service: Amazon S3, AWS Request ID: AE203E7293ZZA3ED, AWS Error Code: null, AWS Error Message: Forbidden

使用piece of Python 和更多代码,我可以列出我的存储桶、列出我的文件、下载文件、从我的计算机读取文件并获取文件 url。 这段代码给了我以下文件网址:

https://my.domain:8080/test_bucket/test_file.txt?Signature=%2Fg3jv96Hdmq2450VTrl4M%2Be%2FI%3D&Expires=1539595614&AWSAccessKeyId=myaccesskey

我应该如何安装/设置/下载以使 spark 能够从我的 S3 服务器读取和写入?

编辑 3:

使用debug tool in comment 这里是the result。 似乎问题在于签名不知道这意味着什么。

【问题讨论】:

见***.com/questions/44411493/… java.lang.NoClassDefFoundError: org/apache/hadoop/fs/StorageStatistics的可能重复 如果您的权限被拒绝,那么您的类路径是正确的... AWS(或 minio)拒绝您的密钥...您可以 minio github 上有关 Spark 支持的问题 忘掉 S3n,它不再被维护并且表现不佳。专注于 s3a 并处理类路径。要调试下载完整的 hadoop 发行版,请将您的 s3a 密钥放入 core-site,然后在 github.com/steveloughran/cloudstore 中运行诊断入口点;它是我指向每个人的自我诊断代码 这是一种说“你的类路径仍然损坏”的方式;那是 hadoop-aws JAR 中的一个文件。对于 Hadoop 3+,您可以编辑 ~/.hadooprc 以将其拉入 `hadoop_add_to_classpath_tools hadoop-aws' 【参考方案1】:

首先,您需要下载与您的 spark-hadoop 版本安装相匹配的 aws-hadoop.jar 和 aws-java-sdk.jar,并将它们添加到 spark 文件夹内的 jars 文件夹中。 然后,如果您的 S3 服务器不支持动态 DNS,您将需要精确您将使用的服务器并启用路径样式:

sc.hadoopConfiguration.set("fs.s3a.path.style.access","true")
sc.hadoopConfiguration.set("fs.s3a.endpoint","my.domain:8080")
#I had to change signature version because I have an old S3 api implementation:
sc.hadoopConfiguration.set("fs.s3a.signing-algorithm","S3SignerType")

这是我的最终代码:

sc.hadoopConfiguration.set("fs.s3a.impl", "org.apache.hadoop.fs.s3a.S3AFileSystem")
val tmp = sc.textFile("s3a://test_bucket/test_file.txt")
sc.hadoopConfiguration.set("fs.s3a.access.key","mykey")
sc.hadoopConfiguration.set("fs.s3a.secret.key","mysecret")
sc.hadoopConfiguration.set("fs.s3a.endpoint","my.domain:8080")
sc.hadoopConfiguration.set("fs.s3a.connection.ssl.enabled","true")
sc.hadoopConfiguration.set("fs.s3a.path.style.access","true")
sc.hadoopConfiguration.set("fs.s3a.signing-algorithm","S3SignerType")
tmp.count()

我建议将大部分设置放入spark-defaults.conf

spark.hadoop.fs.s3a.impl                   org.apache.hadoop.fs.s3a.S3AFileSystem
spark.hadoop.fs.s3a.path.style.access      true
spark.hadoop.fs.s3a.endpoint               mydomain:8080
spark.hadoop.fs.s3a.connection.ssl.enabled true
spark.hadoop.fs.s3a.signing-algorithm      S3SignerType

我遇到的一个问题是将spark.hadoop.fs.s3a.connection.timeout 设置为 10,但是这个值是在 Hadoop 3 之前以毫秒为单位设置的,它会给你一个很长的超时时间;尝试读取文件后 1.5 分钟会出现错误消息。

PS: 特别感谢Steve Loughran. 非常感谢您的宝贵帮助。

【讨论】:

很棒的文章。您不需要设置 spark.hadoop.fs.s3a.impl 顺便说一句,它是从 hadoop-common 中的 /core-default.xml 中的选项自动计算出来的。如果连接超时值已更改,那不是故意的... @kiwy 纠正我,但我认为 aws-java-sdk.jar 的版本是 1.11.x,hadoop 是 2.7.3。因此,我不确定与 spark-hadoop 安装的 hadoop 匹配的版本是什么意思。我找到了 aws-java-sdk.jar v1.11.656 的最大下载量。 @AniruddhaTekade 我的意思是,你应该检查你有什么安装的spark和hadoop,一旦找到你的hadoop版本,最简单的方法是下载相应的hadoop版本并获取命名的 jar 并将它们放在 spark/jars 文件夹中

以上是关于Spark Scala S3 存储:权限被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

AWS S3 访问被拒绝。存储桶权限被授予,那么当我是用户时,我需要存储桶策略吗?

AWS S3 存储桶策略编辑器访问被拒绝

在 Python 中使用 Spark 读取 S3 文件时权限被拒绝

为啥我的 lambda 函数在尝试访问 S3 存储桶时会被拒绝访问?

代号一上传图片到S3存储桶权限

弹性 beantalk 检索 S3 文件时权限被拒绝