我有两个数据帧,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散列函数,我还检查了几个其他连接的分区大小,我也在数字键连接中看到了这个问题。
答案 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)
它给了我关于它的偏斜的很好的信息。