Spark保存(写入)镶木地板只有一个文件

Posted

技术标签:

【中文标题】Spark保存(写入)镶木地板只有一个文件【英文标题】:Spark save(write) parquet only one file 【发布时间】:2019-01-08 18:28:14 【问题描述】:

如果我写

dataFrame.write.format("parquet").mode("append").save("temp.parquet")

在 temp.parquet 文件夹中 我得到了与行号相同的文件号

我认为我对镶木地板的了解并不完全,但它是自然的吗?

【问题讨论】:

【参考方案1】:

写入操作之前使用coalesce

dataFrame.coalesce(1).write.format("parquet").mode("append").save("temp.parquet")


EDIT-1

仔细观察,docs 确实警告 coalesce

但是,如果您要进行剧烈的合并,例如到 numPartitions = 1,这可能会导致您的计算发生在更少的节点上 比你喜欢的(例如,在 numPartitions = 1 的情况下为一个节点)

因此作为suggested by @Amar,最好使用repartition

【讨论】:

我在其他地方读到过,coalesce 的性能更高。我们应该相信谁? 虽然coalesce minimizes data-movement,产生的partitions不一定(事实上,不太可能)大小相同。因此,它实际上是在更少的 shuffle-overhead 和 (almost) 大小相等的分区之间进行权衡。 [1] 因此,一般而言,最好使用coalesce,只有在观察到退化时才回退到repartition[2] 然而,在 numPartitions=1 这个特殊情况下,文档强调 repartition 会是更好的选择 我的意思是洗牌,总是觉得这是最重要的方面,但我同意你的观点,这就是我的观点。很有趣。 谢谢 y2k-shubham,bluephantom 我得到了我想要的!!【参考方案2】:

虽然之前的答案是正确的,但您必须了解重新分区或合并到单个分区后的影响。您的所有数据都必须传输给单个工作人员,以便立即将其写入单个文件。

正如互联网上反复提到的那样,您应该在这种情况下使用repartition,尽管将随机播放步骤添加到执行计划中。此步骤有助于利用集群的功能,而不是按顺序合并文件。

至少有一个替代方案值得一提。您可以编写一个简单的脚本,将所有文件合并为一个文件。这样您就可以避免向集群的单个节点产生大量网络流量。

【讨论】:

谢谢你。现在我正在搜索重新分区和合并!!【参考方案3】:

您可以将分区设置为 1 以保存为单个文件

dataFrame.repartition(1).write.format("parquet").mode("append").save("temp.parquet")

【讨论】:

注意repartition(1)应该在write之前,因为它是Dataset而不是DataFrameWriter的方法

以上是关于Spark保存(写入)镶木地板只有一个文件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Spark 将镶木地板文件加载到 Hive 表中?

Python:将熊猫数据框保存到镶木地板文件

从目录读取镶木地板文件时,pyspark不保存

将rdd保存到镶木地板文件scala

无法将数据框保存到镶木地板 pyspark

使用胶水保存为镶木地板文件时会修改数据帧标头