我已经创建了两个来自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
但是我仍然无法实现性能,因为这些数据帧没有被广播时也是如此。
任何人都可以判断这是否是正确的广播和使用方法?“
答案 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()
这样做可确保数据框
现在运行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数据框。