如何在Spark中访问广播的DataFrame

时间:2016-01-21 18:15:01

标签: scala apache-spark

我已经创建了两个来自Hive表(PC_ITM和ITEM_SELL)并且大小的数据帧,我正在使用这些数据帧 经常在SQL查询中注册为table.But因为它们很大,所以需要花费很多时间 获取查询结果。所以我将它们保存为镶木地板文件,然后将它们读取并注册为临时表。但是我仍然没有获得良好的性能,所以我已经广播了这些数据帧,然后注册为表格如下。

PC_ITM_DF=sqlContext.parquetFile("path")
val PC_ITM_BC=sc.broadcast(PC_ITM_DF)
val PC_ITM_DF1=PC_ITM_BC
PC_ITM_DF1.registerAsTempTable("PC_ITM")

ITM_SELL_DF=sqlContext.parquetFile("path")
val ITM_SELL_BC=sc.broadcast(ITM_SELL_DF)
val ITM_SELL_DF1=ITM_SELL_BC.value
ITM_SELL_DF1.registerAsTempTable(ITM_SELL)


sqlContext.sql("JOIN Query").show

但是我仍然无法实现性能,因为这些数据帧没有被广播时也是如此。

任何人都可以判断这是否是正确的广播和使用方法?“

3 个答案:

答案 0 :(得分:18)

你真的不需要访问'广播数据帧 - 您只需使用它,Spark将在幕后实现广播。 broadcast function 效果很好,更有意义sc.broadcast方法。

如果您一次评估所有内容,可能很难理解花费的时间。

您可以将代码分解为多个步骤。这里的关键是执行操作并在您中使用它们之前保存要广播的数据帧。

// load your dataframe
PC_ITM_DF=sqlContext.parquetFile("path")

// mark this dataframe to be stored in memory once evaluated
PC_ITM_DF.persist()

// mark this dataframe to be broadcast
broadcast(PC_ITM_DF)

// perform an action to force the evaluation
PC_ITM_DF.count()

这样做可确保数据框

  • 加载到内存中(持久)
  • 注册为临时表以供在SQL查询中使用
  • 标记为广播,因此将发送给所有执行者

现在运行sqlContext.sql("JOIN Query").show时,您现在应该看到一个'广播哈希加入'在Spark UI的SQL选项卡中。

答案 1 :(得分:0)

我会将rdds缓存在内存中。下次需要时,spark会从内存中读取RDD,而不是每次都从头开始生成RDD。以下是快速入门docs的链接。

val PC_ITM_DF = sqlContext.parquetFile("path")
PC_ITM_DF.cache()
PC_ITM_DF.registerAsTempTable("PC_ITM")

val ITM_SELL_DF=sqlContext.parquetFile("path")
ITM_SELL_DF.cache()
ITM_SELL_DF.registerAsTempTable("ITM_SELL")
sqlContext.sql("JOIN Query").show

rdd.cache()是rdd.persist(StorageLevel.MEMORY_ONLY)的简写。您可以选择几种级别的持久性,因为您的数据太大而不能仅用于内存持久性。这是list of persistence options.如果您想从缓存中手动删除RDD,可以调用rdd.unpersist()

如果您希望广播数据。您必须先在驱动程序上收集它,然后才能进行广播。这要求您的RDD适合您的驱动程序(和执行者)的内存。

答案 2 :(得分:0)

此时您无法访问SQL查询中的广播数据框。您只能通过数据框使用brocasted数据框。

参考:https://issues.apache.org/jira/browse/SPARK-16475