Amazon s3a 使用 Spark 返回 400 Bad Request

Posted

技术标签:

【中文标题】Amazon s3a 使用 Spark 返回 400 Bad Request【英文标题】:Amazon s3a returns 400 Bad Request with Spark 【发布时间】:2016-03-16 12:28:27 【问题描述】:

出于结帐目的,我尝试将 Amazon S3 存储桶设置为检查点文件。

val checkpointDir = "s3a://bucket-name/checkpoint.txt"
val sc = new SparkContext(conf)
sc.setLocalProperty("spark.default.parallelism", "30")
sc.hadoopConfiguration.set("fs.s3a.access.key", "xxxxx")
sc.hadoopConfiguration.set("fs.s3a.secret.key", "xxxxx")
sc.hadoopConfiguration.set("fs.s3a.endpoint", "bucket-name.s3-website.eu-central-1.amazonaws.com")
val ssc = new StreamingContext(sc, Seconds(10))
ssc.checkpoint(checkpointDir)

但它会因这个异常而停止

Exception in thread "main" com.amazonaws.services.s3.model.AmazonS3Exception: Status Code: 400, AWS Service: Amazon S3, AWS Request ID: 9D8E8002H3BBDDC7, AWS Error Code: null, AWS Error Message: Bad Request, S3 Extended Request ID: Qme5E3KAr/KX0djiq9poGXPJkmr0vuXAduZujwGlvaAl+oc6vlUpq7LIh70IF3LNgoewjP+HnXA=
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:798)
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:421)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:232)
at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:3528)
at com.amazonaws.services.s3.AmazonS3Client.headBucket(AmazonS3Client.java:1031)
at com.amazonaws.services.s3.AmazonS3Client.doesBucketExist(AmazonS3Client.java:994)
at org.apache.hadoop.fs.s3a.S3AFileSystem.initialize(S3AFileSystem.java:154)
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2596)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:91)
at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2630)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2612)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:370)
at org.apache.hadoop.fs.Path.getFileSystem(Path.java:296)
at org.apache.spark.streaming.StreamingContext.checkpoint(StreamingContext.scala:232)
at com.misterbell.shiva.StreamingApp$.main(StreamingApp.scala:89)
at com.misterbell.shiva.StreamingApp.main(StreamingApp.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:664)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:169)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:192)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:111)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)

我不明白为什么会出现此错误,也找不到任何示例。

【问题讨论】:

【参考方案1】:

此消息对应于“错误端点”或错误签名版本支持之类的内容。

就像看到的herefrankfurt 是唯一不支持签名版本 2 的。这是我选择的。

当然,毕竟我的研究不能说什么是签名版本,在文档中并不明显。但是 V2 似乎可以与 s3a 一起使用。

在 S3 界面中看到的端点不是真正的端点,它只是 Web 端点。

您必须像这样使用theses 端点之一 sc.hadoopConfiguration.set("fs.s3a.endpoint", "s3.eu-west-1.amazonaws.com")

但默认情况下它适用于美国端点

【讨论】:

我可以确认不同的 aws 区域使用不同的版本,例如。沙256。所以应该尝试使用最新的兼容版本,例如。 aws-java-sdk 的 上述命令在 PySpark 中的等价物是 sc._jsc.hadoopConfiguration().set("fs.s3a.endpoint", "s3.eu-west-1.amazonaws.com")【参考方案2】:

如果您想在 spark 中使用支持 Signature V4 的区域,您可以在运行时将标志 -Dcom.amazonaws.services.s3.enableV4 传递给驱动程序选项和执行程序选项。例如:

spark-submit --conf spark.driver.extraJavaOptions='-Dcom.amazonaws.services.s3.enableV4' \
    --conf spark.executor.extraJavaOptions='-Dcom.amazonaws.services.s3.enableV4' \
    ... (other spark options)

使用此设置,即使使用不太新鲜的 AWS sdk 版本(在我的情况下为com.amazonaws:aws-java-sdk:1.7.4),Spark 也能够写入法兰克福(和其他仅 V4 的区域)

【讨论】:

哪个 Spark 版本? 2.4? 是的,我在 2.4.3 中使用过 我自己也试过了,但遇到了一些其他问题,想知道你是否用 2.4 尝试过。现在它也适用于我。谢谢! 尝试使用 Spark 2.4.5,我必须同时执行此操作和 @crak 的回复才能让 Spark 读取区域 ap-south-1 的文件。其中任何一个单独是不够的。正在使用com.amazonaws:aws-java-sdk:1.7.4 这救了我%spark.conf spark.jars /spark-additional-jars/spark-avro_2.11-2.4.3.jar,/spark-additional-jars/hudi-spark-bundle_2.11-0.6.0.jar,/spark-additional-jars/hudi-utilities-bundle_2.11-0.6.0.jar,/spark-additional-jars/hadoop-aws-2.7.3.jar,/spark-additional-jars/hadoop-common-2.7.3.jar,/spark-additional-jars/aws-java-sdk-1.7.4.jar spark.serializer org.apache.spark.serializer.KryoSerializer spark.executor.extraJavaOptions -Dcom.amazonaws.services.s3.enableV4 extraJavaOptions - 我们的救星【参考方案3】:

我在本地运行 spark 时遇到了同样的问题,因为我没有设置 SIGV4,这段代码帮助了我:

import com.amazonaws.SDKGlobalConfiguration
System.setProperty(SDKGlobalConfiguration.ENABLE_S3_SIGV4_SYSTEM_PROPERTY, "true")

【讨论】:

我在点击 S3 Bucket 从 android 应用程序上传文件时也遇到了同样的问题。我正在使用改造库。

以上是关于Amazon s3a 使用 Spark 返回 400 Bad Request的主要内容,如果未能解决你的问题,请参考以下文章

使用 PySpark 从 Amazon S3 读取文本文件

使用 Spark 访问 s3a 时出现 403 错误

您可以在 Spark/Hadoop 中将 s3:// 翻译(或别名)为 s3a:// 吗?

使用 Spark 通过 s3a 将 parquet 文件写入 s3 非常慢

如何在 Spark Submit 中将 s3a 与 Apache spark 2.2(hadoop 2.8) 一起使用?

Apache Spark s3a 提交者 - 线程堆栈 - 内存不足问题