如何均匀分布数据集以避免偏斜连接(以及长时间运行的任务)?

时间:2017-10-21 07:35:56

标签: apache-spark join apache-spark-sql

我在databricks笔记本上使用Spark数据集API编写应用程序。

我有2张桌子。一个是15亿行,第二个是250万行。两个表都包含电信数据,并且使用国家代码和数字的前5位数来完成连接。输出有550亿行。问题是我有数据偏差(长时间运行的任务)。无论我如何重新分配数据集,由于散列键的分布不均匀,我得到了长时间运行的任务。

我尝试使用广播连接,尝试在内存中保留大表分区等.....

我有什么选择?

1 个答案:

答案 0 :(得分:5)

spark会根据连接键重新分配数据,因此在加入之前重新分区不会改变偏斜(只添加不必要的随机播放)

如果您知道导致偏斜的键(通常会出现类似null或0或""),请将数据拆分为2个部分 - 带有倾斜键的1个数据集,和其他人一起

并在子数据集上进行连接,并结合结果

例如:

val df1 = ...
val df2 = ...
val skewKey = null

val df1Skew = df1.where($"key" === skewKey)
val df2Skew = df2.where($"key" === skewKey)

val df1NonSkew = df1.where($"key" =!= skewKey)
val df2NonSkew = df2.where($"key" =!= skewKey)

val dfSkew    = df1Skew.join(df2Skew) //this is a cross join
val dfNonSkew = df1NonSkew.join(df2NonSkew, "key")

val res = dfSkew.union(dfNonSkew)