如何并行处理数据但将结果写入 Spark 中的单个文件

Posted

技术标签:

【中文标题】如何并行处理数据但将结果写入 Spark 中的单个文件【英文标题】:How to process data in parallel but write results in a single file in Spark 【发布时间】:2018-10-31 13:03:29 【问题描述】:

我有一份 Spark 工作:

从 hdfs 读取数据 进行一些密集的转换没有洗牌和聚合(仅映射操作) 将结果写回 hdfs

假设我有 10GB 的原始数据(40 个块 = 40 个输入分区),这会产生 100MB 的处理数据。为了避免在 hdfs 中生成许多小文件,我使用“coalesce(1)”语句来编写带有结果的单个文件。 这样做我只运行了 1 个任务(因为“coalesce(1)”并且没有洗牌),它在一个线程中处理所有 10GB。

有没有办法在 40 个并行任务中进行实际的密集处理,并在写入磁盘之前减少分区数量并避免数据混洗?

我有一个可能可行的想法 - 在所有处理后将数据帧缓存在内存中(进行计数以强制 Spark 缓存数据),然后放入“coalesce(1)”并将数据帧写入磁盘

【问题讨论】:

【参考方案1】:

文档清楚地警告了这种行为并提供了解决方案:

但是,如果您要进行剧烈的合并,例如对于 numPartitions = 1,这可能会导致您在比您喜欢的更少的节点上进行计算(例如,在 numPartitions = 1 的情况下为一个节点)。为避免这种情况,您可以调用 repartition。这将添加一个 shuffle 步骤,但意味着当前的上游分区将并行执行(无论当前分区是什么)。

所以改为

coalesce(1)

你可以试试

repartition(1)

【讨论】:

谢谢!确实有道理:)

以上是关于如何并行处理数据但将结果写入 Spark 中的单个文件的主要内容,如果未能解决你的问题,请参考以下文章

Spark RDD:如何共享数据以进行并行操作

Spark 中的并行集合

Spark写入postgres慢

聊聊批计算、流计算、Hadoop、Spark、Storm、Flink等等

如何在单个 Spark 作业中摄取不同的 Spark 数据帧

如何将多个表的结果写入配置单元中的单个表?