我想在许多分区上进行计算,从并行性中受益,然后将我的结果写入单个文件,可能是镶木地板文件。我在PySpark 1.6.0中尝试过的工作流程如下:
data_df = sqlContext.read.load('my_parquet_file')
mapped_df = sqlContext.createDataFrame(data_df.map(lambda row: changeRow(row)), ['c1', 'c2'])
coalesced_df = mapped_df.coalesce(1)
coalesced_df.write.parquet('new_parquet_file')
但是从看看Spark的Web UI看来,所有的工作,包括map
部分都发生在一个线程上。
有没有办法调整这个以便map
在许多分区上发生而write
仅在1上发生?我认为唯一可行的方法是在mapped_df.count()
和map
之间加coalesce
,但这并不是一种令人满意的方式。这样做。
答案 0 :(得分:2)
Spark做懒惰评估意味着在调用动作之前它不会执行任何操作。 write
和count
都是将 tricker执行的操作。像map
和filter
这样的函数很容易执行而执行某些操作 - 而不是之前执行某些操作。
现在,您的管道非常简单,只有一个操作(write
),因此在编写文件时正在执行 {em}。然而,通过调用map
,您还可以告诉Spark在执行coalesce(1)
操作之前将所有数据收集到一个分区中,并且因为write
是其中的一部分。在map
操作中执行,write
也将在一个分区中运行。
我希望这是有道理的。我建议你也阅读一些关于Spark如何工作的博客文章。来自Cloudera的This one,应该给你一些见解:)
答案 1 :(得分:1)
您想使用“repartition(1)”而不是“coalesce(1)”。问题在于“重新分配”将很乐意改变以实现其目的,而“合并”则不会。