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

dat*_*ack 4 join apache-spark apache-spark-sql

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

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

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

我有什么选择?

lev*_*lev 5

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

如果你知道导致歪斜的键(通常它会是一些像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)
Run Code Online (Sandbox Code Playgroud)