【发布时间】:2019-01-08 18:28:14
【问题描述】:
如果我写
dataFrame.write.format("parquet").mode("append").save("temp.parquet")
在 temp.parquet 文件夹中 我得到了与行号相同的文件号
我认为我对镶木地板的了解并不完全,但它是自然的吗?
【问题讨论】:
标签: scala apache-spark parquet
如果我写
dataFrame.write.format("parquet").mode("append").save("temp.parquet")
在 temp.parquet 文件夹中 我得到了与行号相同的文件号
我认为我对镶木地板的了解并不完全,但它是自然的吗?
【问题讨论】:
标签: scala apache-spark parquet
在写入操作之前使用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 minimizes data-movement,产生的partitions不一定(事实上,不太可能)大小相同。因此,它实际上是在更少的 shuffle-overhead 和 (almost) 大小相等的分区之间进行权衡。 [1] 因此,一般而言,最好使用coalesce,只有在观察到退化时才回退到repartition[2] 然而,在 numPartitions=1 这个特殊情况下,文档强调 repartition 会是更好的选择
虽然之前的答案是正确的,但您必须了解重新分区或合并到单个分区后的影响。您的所有数据都必须传输给单个工作人员,以便立即将其写入单个文件。
正如互联网上反复提到的那样,您应该在这种情况下使用repartition,尽管将随机播放步骤添加到执行计划中。此步骤有助于利用集群的功能,而不是按顺序合并文件。
至少有一个替代方案值得一提。您可以编写一个简单的脚本,将所有文件合并为一个文件。这样您就可以避免向集群的单个节点产生大量网络流量。
【讨论】:
您可以将分区设置为 1 以保存为单个文件
dataFrame.repartition(1).write.format("parquet").mode("append").save("temp.parquet")
【讨论】:
repartition(1)应该在write之前,因为它是Dataset而不是DataFrameWriter的方法