我正致力于改进我正在进行原型设计的推荐引擎的一些Spark操作的性能。我偶然发现我正在使用的DataFrame之间存在显着的性能差异。低于两者上describe()的结果。
df1(fast,numPartitions = 4):
+-------+------------------+--------------------+
|summary| item_id| popularity|
+-------+------------------+--------------------+
| count| 187824| 187824|
| mean| 96693.34836868558| 1.0|
| stddev|55558.023793621316|5.281958866780519...|
| min| 0| 0.9999999999999998|
| max| 192806| 1.0|
+-------+------------------+--------------------+
df2(约慢10倍,numPartitions =±170):
+-------+-----------------+-----------------+
|summary| item_id| count|
+-------+-----------------+-----------------+
| count| 187824| 187824|
| mean|96693.34836868558|28.70869537439305|
| stddev|55558.02379362146|21.21976457710462|
| min| 0| 1|
| max| 192806| 482|
+-------+-----------------+-----------------+
两个DataFrame都被缓存,在行(187824)和列(2)方面具有相同的大小,并且具有相同的item_id
列。主要区别在于第1帧在第二列中包含float,而第2帧包含整数。
似乎DataFrame 2的每个操作都要慢得多,从简单的.describe().show()
操作到更精细的.subtract().subtract().take()
。在后一种情况下,DataFrame 2需要18秒,而帧1需要2秒(几乎慢10倍!)。
我不知道从哪里开始寻找这种差异原因的解释。非常感谢任何正确方向的提示或推动。
更新:正如Viacheslav Rodionov所建议的那样,数据帧的分区数似乎是df2性能问题的原因。
深入挖掘,两个数据帧都是对同一原始数据帧进行.groupBy().agg().sortBy()
操作的结果。 .groupBy().agg()
操作产生200个分区,然后.sortBy()
分别返回4和±170个分区,为什么会这样?
答案 0 :(得分:4)
我将从查看df.rdd.getNumPartitions()
较小数量的较大分区几乎总是一个好主意,因为它可以更好地压缩数据并执行更多实际工作而不是操作文件。
要看的另一件事是你的数据是怎样的。是否适合您正在尝试的任务?
BETWEEN
操作的日期字段进行排序,它将比使用未排序数据更快。 我存储数据时的经验法则 - 首先按少数低基数字段(主要是布尔和日期)划分,然后按数据重要性顺序对{strong>所有其他字段sortWithinPartitions
进行排序。这样,您将获得最佳压缩率(意味着更快的处理时间)和更好的数据局部性(再次更快的处理时间)。但一如既往,这一切都取决于您的使用案例,始终考虑如何处理您的数据并做出相应的准备。