Spark Dataframes:加入后偏斜的分区

时间:2016-12-12 04:18:26

标签: python apache-spark pyspark apache-spark-sql spark-dataframe

我有两个数据帧,df1有2200万条记录,df2有200万条记录。我正在email_address作为关键进行正确的加入。

test_join = df2.join(df1, "email_address", how = 'right').cache()

两个数据框中都有很少的重复(如果有)电子邮件。在加入之后,我正在尝试使用以下代码查找结果数据框test_join的分区大小:

l = builder.rdd.mapPartitionsWithIndex(lambda x,it: [(x,sum(1 for _ in it))]).collect()
print(max(l,key=lambda item:item[1]),min(l,key=lambda item:item[1]))

结果显示,最大分区比平均分区大小大100倍。分区大小的这种偏差会在连接后转换和操作中产生性能问题。

我知道我可以在使用repartion(num_partitions)命令进行连接后对其进行同样的重新分区,但我的问题是为什么我遇到这种不均匀的分区结果,并且有什么方法可以首先避免它。< / p>

P.S:只是为了检查问题是否只有email_address散列函数,我还检查了几个其他连接的分区大小,我也在数字键连接中看到了这个问题。

1 个答案:

答案 0 :(得分:3)

@ user6910411你被发现了。问题在于我的数据,输入空的电子邮件之后有一些愚蠢的惯例,这导致了这个歪斜键问题。

在检查了最大分区的肠衣时,我才知道那里发生了什么。我发现这种调试技术非常有用,我相信这可以帮助那些面临同样问题的人。

BTW,这是我写的函数,用于查找RDD分区的偏差:

from itertools import islice
def check_skewness(df):
    sampled_rdd = df.sample(False,0.01).rdd.cache() # Taking just 1% sample, to make processing fast
    l = sampled_rdd.mapPartitionsWithIndex(lambda x,it: [(x,sum(1 for _ in it))]).collect()
    max_part = max(l,key=lambda item:item[1])
    min_part = min(l,key=lambda item:item[1])
    if max_part[1]/min_part[1] > 5: #if difference between largest and smallest partition size is greater than 5 times
        print 'Partitions Skewed: Largest Partition',max_part,'Smallest Partition',min_part,'\nSample Content of the largest Partition: \n'
        print (sampled_rdd.mapPartitionsWithIndex(lambda i, it: islice(it, 0, 5) if i == max_part[0] else []).take(5))
    else:
        print 'No Skewness: Largest Partition',max_part,'Smallest Partition',min_part

然后我只传递我想要检查偏斜的数据帧,如下所示:

check_skewness(test_join)

它给了我关于它的偏斜的很好的信息。