如何在pyspark中并行编写多个镶木地板文件?

时间:2016-11-30 11:08:42

标签: python pyspark parquet

我想将数据框拆分为两个数据框并将它们写入两个单独的镶木地板文件,如

df = attachment_df.flatMap(process_attachment).toDF()

large_df = df.filter(df.is_large_file == True)
small_df = df.filter(df.is_large_file == False)

(large_df.write
    .mode("overwrite")
    .parquet('large_dummy'))

(small_df.write
    .mode("overwrite")
    .parquet('small_dummy'))

但是,上面的代码将按顺序写入,看起来每个附件都会调用process_attachment函数两次。我真的想避免重复计算,因为处理附件非常昂贵。

有没有办法避免重复处理附件和并行写入?我不想使用is_large_file列的分区写入单个镶木地板文件。

谢谢,

1 个答案:

答案 0 :(得分:3)

当spark写入时,它会为每个数据帧并行写入(基于分区数)。所以你基本上是连续两个并行的任务(即不应该有很大的影响)。 主要问题是目前你正在重新计算两次df。

原因是DAG是针对每个动作单独计算的(写作是动作)。

如果你有足够的内存,你可以通过在第一次写入之前执行df.cache()和在第二次写入之后执行df.unpersist来改进这一点。这将在内存中保留df的计算(即有足够的内存)。

如果你没有足够的内存且process_attachment真的很长,你可以尝试使用MEMORY_AND_DISK选项的持久化,如果它太大(即你将从磁盘重新加载而不是重新计算)将计算溢出到磁盘上。