Spark重用广播DF

时间:2019-07-07 17:56:24

标签: apache-spark

我想重用我的DataFrame(在RDD / Dataset中使用“ Map”功能不退一步),我将其标记为可广播,但是似乎Spark不断地广播它。

具有表“ bank”(测试表)。我执行以下操作:

  val cachedDf = spark.sql("select * from bank").cache
  cachedDf.count

  val dfBroadcasted = broadcast(cachedDf)

  val dfNormal = spark.sql("select * from bank")

  dfNormal.join(dfBroadcasted, List("age"))
    .join(dfBroadcasted, List("age")).count

在进行缓存之前,以防万一它有所作为,但是无论有无,它都是相同的。

如果执行上述代码,则会看到以下SQL计划:

SQL plan for the code

如您所见,我广播的DF广播TWICE的时间也不同(如果以后添加更多操作,它们也会再次广播)。

我对此很在意,因为我实际上有一个长期运行的程序,其中包含一个“大” DataFrame,可以用来过滤掉巨大的DataFrame,并且我希望该“大” DataFrame可以重用。

有没有办法强制可重用性? (不仅在同一动作内,而且在动作之间,我也可以通过相同的动作生存下来)

谢谢!,

1 个答案:

答案 0 :(得分:2)

好,更新问题。

总结: 在同一动作中,left_semis将重用广播 而普通/左联接则不会。不确定是否与Spark /开发人员已经知道DF的列完全不会影响输出这样的事实有关,因此他们可以重复使用它,或者只是缺少优化火花。

我的问题似乎可以解决,尽管有人知道如何保持动作间的广播会很好。

如果我使用left_semi(这是我将在我的实际应用中使用的联接),则广播仅执行一次。

使用:

    dfNormalxx.join(dfBroadcasted, Seq("age"),"left_semi")
.join(dfBroadcasted, Seq("age"),"left_semi").count

计划变成了(我也更改了尺寸,使其与我的真实尺寸相匹配,但这没有区别):

enter image description here

与使用“ left_semi”相比,隔离墙的总时间要好得多(我设置了1个执行程序,因此它不会并行化,只想检查作业是否真的完成了两次):

enter image description here

即使我的收集花费了10秒,这也会加快表格读取+ groupBy的过程,这大约需要6-7分钟的时间