hadoop - 在不创建 _temporary 文件夹的情况下将 Spark 数据帧作为 Parquet 写入 S3

标签 hadoop apache-spark amazon-s3 pyspark

我正在使用 pyspark 从 Amazon S3 上的 Parquet 文件中读取数据帧,例如

dataS3 = sql.read.parquet("s3a://" + s3_bucket_in)

这没有问题。但是后来我尝试写数据

dataS3.write.parquet("s3a://" + s3_bucket_out)

我确实得到以下异常

py4j.protocol.Py4JJavaError: An error occurred while calling o39.parquet.
: java.lang.IllegalArgumentException: java.net.URISyntaxException: 
Relative path in absolute URI: s3a://<s3_bucket_out>_temporary

在我看来,Spark 正在尝试先创建一个 _temporary 文件夹,然后再写入给定的存储桶。这可以以某种方式防止,以便 spark 直接写入给定的输出桶吗?

最佳答案

您不能删除 _temporary 文件,因为它用于保留中间文件 在完成之前隐藏查询的工作

但这没关系,因为这不是问题所在。问题是输出提交者在尝试写入根目录时有点困惑(无法删除它,请参阅)

您需要写入存储桶下的子目录,并带有完整前缀。例如 s3a://mybucket/work/out

我应该补充一点,尝试将数据提交到 S3A 是不可靠的,正是因为它模仿 rename() 的方式类似于 ls -rlf src | xargs -p8 -I% "cp % dst/% && rm %"。因为 ls 在 S3 上延迟了一致性,它可能会错过新创建的文件,所以不要复制它们。

参见:Improving Apache Spark了解详情。

现在,您只能通过写入 HDFS 然后复制来可靠地提交到 s3a。 EMR s3 通过使用 DynamoDB 提供一致的列表来解决这个问题

关于hadoop - 在不创建 _temporary 文件夹的情况下将 Spark 数据帧作为 Parquet 写入 S3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46464065/

相关文章:

hadoop - Oozie 无法检测 XML 中的 Spark workflow-app 标签

bash - 如何获取hiveQL脚本花费的时间

sql - 如何使用配置单元计算字符串中的唯一整数?

scala - 使用 Spark Streaming 上下文时如何将 Seq 转换为 RDD

scala - Scala Spark 中笛卡尔变换的显式排序

java - 从java aws lambda访问s3

java - AWS无法计算MD5哈希Android

hadoop - 如何更改Hadoop中数据 block 的大小?

scala - Spark保存(写入) Parquet 只有一个文件

ruby-on-rails-4 - Ruby on Rails 4 Heroku 应用程序在上传大尺寸视频时崩溃