Spark版本1.6.0
我正在使用两个具有100个分区的数据框之间的连接功能,该应用程序在一个群集上运行,在该群集上,我为每20个执行程序使用5个内核,总共有100个内核。
我的问题是,当我进行联接时,所有记录都是在一个执行器上计算的,而其他执行器则没有如下图所示:
这会导致性能下降,因为所有数据都是由一个执行程序计算出来的,而不是其他19个可用执行程序计算的。
spark join似乎仅在一个分区中“带来”所有记录,有没有办法避免这种情况?
为确保不会将其分割为1,我还设置了以下spark属性:spark.sql.shuffle.partitions=100
实际上,两个输入数据帧具有与输出数据帧相同的100个分区
答案 0 :(得分:1)
简短回答:
这是因为您的数据,而不是因为火花。
长答案:
为了执行join
操作,spark需要将具有相同键(要连接的列的值)的数据移动到相同的工作程序。例如。如果将A列与B列连接在一起,则两个表中包含相同值的行将移至相同的工作程序,然后再连接。
此外-具有不同键的行也可能会移动到同一节点-这取决于您拥有的Partitioner。您可以阅读更多here-但可以了解默认分区程序的一般概念-HashPartitioner
和RangePartitioner
。不管使用哪一个,它都会决定在哪一行工作。例如-如果您的RangePartitioner的范围为[0,5)[5。 7)[7,10],则键1、2、3、4都将移至同一工人。而且,如果您的数据中仅包含这些密钥,则只会利用一名工作人员。