在 spark、collect() 或 toLocalIterator() 中速度更快

AMA*_*NGH 7 apache-spark

我有一个 spark 应用程序,我需要在其中将数据从执行程序获取到驱动程序,并且我正在使用collect(). 不过,我也遇到过toLocalIterator()。就我toLocalIterator()在 Internet 上读到的内容而言,它返回一个迭代器而不是立即发送整个 RDD,因此它具有更好的内存性能,但是速度呢?执行/计算时间之间collect()和之间的性能如何toLocalIterator()

小智 12

这个问题的答案取决于你在制作df.collect()和后会做什么df.rdd.toLocalIterator()。例如,如果您正在处理一个大约 7M 行的相当大的文件,并且对于其中的每条记录,在完成所有必需的转换之后,您需要迭代 DataFrame 中的每条记录并批量进行服务调用100. 在 的情况下df.collect(),它将把整个记录集转储到驱动程序,因此驱动程序将需要大量的内存。在 的情况下toLocalIterator(),它只会返回总记录分区上的迭代器,因此驱动程序不需要拥有大量内存。因此,如果您打算在同一集群内的并行工作流程中加载如此大的文件,df.collect()将会导致您产生大量费用,而 as toLocalIterator() 不会,而且它也会更快、更可靠。

另一方面,如果您计划在df.collect()或之后进行一些转换df.rdd.toLocalIterator(),那么df.collect()会更快。

此外,如果您的文件非常小,以至于 Spark 的默认分区逻辑根本不会将其分解为分区,那么速度df.collect()会更快。


zer*_*323 5

文档中toLocalIterator()引用:

这会导致多个 Spark 作业,并且如果输入 RDD 是广泛转换的结果(例如加入不同的分区器),为了避免重新计算输入 RDD 应该首先缓存。

这意味着在最坏的情况下(根本没有缓存)它可能比collect. 即使 data 是cached,在大型数据集上启动多个 Spark 作业的开销也可能很大。然而,根据特定的配置,较低的内存占用可以部分弥补这一点。

总的来说,这两种方法都是低效的,应该避免在大型数据集上使用。