【问题标题】:Writing Spark dataframe as parquet to S3 without creating a _temporary folder在不创建 _temporary 文件夹的情况下将 Spark 数据帧作为镶木地板写入 S3
【发布时间】:2017-09-28 08:08:08
【问题描述】:

我正在使用 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 直接写入给定的输出存储桶吗?

【问题讨论】:

标签: hadoop apache-spark amazon-s3 pyspark


【解决方案1】:

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

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

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

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

详情请见:Improving Apache Spark

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

【讨论】:

  • 我能否强制 spark 不将 _temporary 文件夹放到 S3 上,而是将其存储在本地?
  • 不,因为它是提交算法的核心部分。 Executors在_temporary下写入数据;当所有工作人员都完成后,驱动程序会使用重命名来提交它......这只适用于单个文件系统。
  • @SteveLoughran 你好,Steeve,我刚刚看到这个会议youtube.com/watch?v=BgHrff5yAQo 顺便感谢你,一年后有没有更好的方法或者仍然是同一个问题?
  • 是的,Hadoop 3.1 中的 S3A 提交者(在 HDP-3.0 中提供)不使用重命名来提交工作。我们从 Ryan Blye 那里提取了很多代码。 Ryan 这些天也忙于冰山:看看那个
【解决方案2】:

我在写 S3 存储桶的根时遇到了同样的问题:

df.save("s3://bucketname")

我通过在存储桶名称后添加/ 解决了这个问题:

df.save("s3://bucketname/")

【讨论】:

    猜你喜欢
    • 2020-04-03
    • 1970-01-01
    • 2020-03-23
    • 2019-03-04
    • 2020-06-30
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    相关资源
    最近更新 更多