首页 文章

将数据倾斜到少数执行者

提问于
浏览
-2

我在具有 21 个执行程序的独立模式下运行 spark,并且当我使用 sqlContext 加载我的第一个 SQL 表时,我以某种方式对它进行分区,以使数据可以通过在连续整数列上进行分区而在所有块之间完美分配:

val brDF = sqlContext.load("jdbc", Map("url" -> srcurl, "dbtable" -> "basereading", "partitionColumn" -> "timeperiod", "lowerBound" ->"2", "upperBound" -> "35037", "numPartitions" -> "100"))

此外,这些块很好地分布在每个群集上,因此每个群集具有相似的内存使用情况。不幸的是,当我以较小的表 idoM 加入它时,如下所示:

val mrDF = idoM.as('idom).join(brS1DF.as('br), $"idom.idoid" === $"br.meter")

在 idoM 是 1 列表并缓存结果的情况下,RDD 块在集群上的存储方式的分布发生了变化:

Spark UI 执行程序的屏幕快照,按 RDD 块数排序

现在,我的第四个集群上突然有更多的 RDD 块,它使用了更多的内存。在检查每个 RDD 时,它们的块似乎仍然分布良好,因此我的分区仍然很好,只是所有的块似乎只想写在一个集群上,从而打消了以多个块开头的目的。

我怀疑我的问题与Apache 邮件列表上的这个问题类似,但没有答案,因此,不胜感激。

2 回答

  • 1

    我不知道您的数据,我认为您要加入的键的分布是造成数据偏斜的原因。

    运行idoM.groupBy("idoid").count.orderBy(desc("count")).showbrS1DF.groupBy("meter").count.orderBy(desc("count")).show可能会向您显示一些值经常出现。

  • 0

    问题在于将 idoM 加载到一台计算机上,并试图保持数据局部性并在一台计算机上进行整个联接,在这种情况下,通过将较小的表广播到较大的表来解决。我确保 idoM 的键完美地分布在要连接的列上,但是不幸的是,重新分区不能解决问题,因为 spark 仍试图保持局部性,整个 dataFrame 仍然在一台机器上。

相关问题