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

如果我写

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

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

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

【问题讨论】:

    标签: scala apache-spark 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")
    

    【讨论】:

    猜你喜欢
    • 2019-06-02
    • 2017-03-17
    • 2019-09-23
    • 2020-03-11
    • 2019-11-27
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多