Apache spark 数据帧连接优化-广播哈希连接

Apache spark 数据帧连接优化-广播哈希连接,apache-spark,dataframe,apache-spark-sql,apache-spark-1.4,Apache Spark,Dataframe,Apache Spark Sql,Apache Spark 1.4,我试图有效地连接两个数据帧,其中一个较大,另一个较小 有没有办法避免这种混乱?我无法设置autoBroadCastJoinThreshold,因为它只支持整数,而且我尝试广播的表略大于整数字节数 是否有办法强制广播忽略此变量?这是spark的当前限制,请参阅。2GB限制也适用于广播变量 您确定没有其他好方法可以做到这一点,例如不同的分区吗 否则,您可以通过手动创建多个广播变量来绕过它,每个变量您可以使用left.join(broadcast(right),…)广播散列联接(类似于Mapreduc

我试图有效地连接两个数据帧,其中一个较大,另一个较小

有没有办法避免这种混乱?我无法设置
autoBroadCastJoinThreshold
,因为它只支持整数,而且我尝试广播的表略大于整数字节数


是否有办法强制广播忽略此变量?

这是spark的当前限制,请参阅。2GB限制也适用于广播变量

您确定没有其他好方法可以做到这一点,例如不同的分区吗


否则,您可以通过手动创建多个广播变量来绕过它,每个变量您可以使用
left.join(broadcast(right),…)

广播散列联接(类似于Mapreduce中的映射侧联接或映射侧合并)来提示要广播的数据帧: 在SparkSQL中,您可以通过调用
queryExecution.executedPlan
来查看正在执行的联接类型。与core Spark一样,如果其中一个表比另一个表小得多,则可能需要广播哈希连接。您可以通过调用
DataFrame
上的方法
broadcast
来提示Spark SQL,在加入一个给定的DF之前,应该对其进行广播以进行加入

示例:
largedataframe.join(广播(smalldataframe),“键”)

在DWH术语中,其中大数据帧可能类似于事实 smalldataframe可能类似于维度

如我最喜欢的书(HPS)所述,请。请参见下文,以便更好地理解。。

注意:上面的
broadcast
来自
import org.apache.spark.sql.functions.broadcast
而非
SparkContext

Spark还会自动使用
Spark.sql.conf.autoBroadcastJoinThreshold
来确定是否应该广播表

提示:请参阅DataFrame.explain()方法
有没有办法强制广播忽略此变量?
sqlContext.sql(“SET spark.sql.autoBroadcastJoinThreshold=-1”)

注意:

另一个类似的开箱即用说明w.r.t.蜂箱(非spark):类似 使用hive hint
MAPJOIN
可以实现以下功能


进一步阅读:请参阅我的设置
spark.sql.autoBroadcastJoinThreshold=-1
将完全禁用广播。看见
.

我发现这段代码适用于Spark 2.11版本2.0.0中的广播连接

import org.apache.spark.sql.functions.broadcast  

val employeesDF = employeesRDD.toDF
val departmentsDF = departmentsRDD.toDF

// materializing the department data
val tmpDepartments = broadcast(departmentsDF.as("departments"))

import context.implicits._

employeesDF.join(broadcast(tmpDepartments), 
   $"depId" === $"id",  // join by employees.depID == departments.id 
   "inner").show()

下面是上述代码的参考

使用连接提示将优先于配置
autoBroadCastJoinThreshold
,因此使用提示将始终忽略该阈值

此外,当使用连接提示时(因为Spark 3.x),也不会更改提示中给出的策略

Spark SQL中,可以应用连接提示,如下所示:

选择/*+BROADCAST*/a.id,a.id=b.id上连接b的a.value
选择/*+BROADCASTJOIN*/a.id,a.id=b.id上的连接b中的a.value
选择/*+MAPJOIN*/a.id,从a.id=b.id上的连接b中选择a.value

请注意,关键字BROADCAST、BROADCASTJOIN和MAPJOIN都是中的代码中所写的别名。

我已设法将较小表的大小减小到略低于2GB的大小,但似乎无论如何都不会进行广播。(autoBroadcast就是不会选它)。不过,它在小表(100 MB)上运行良好。对于此广播,什么是正确的导入?我发现这个符号
broadcast
是不可解析的。它位于org.apache.spark.sql.functions下,您需要spark 1.5.0或newerAny机会提示广播连接到sql语句?您确实可以在sql语句中使用该提示,但不确定这能起多大作用。e、 g.我使用过它,比如
左内部连接广播(右)
不确定它是否能与子查询一起工作要在SparkSQL中广播,你可以例如:
val df=broadcast(spark.table(“table”).createTempView(“tableAView”)
spark.sql(“从tableAView a join tableB中选择…)感觉你的实际问题是“有没有办法强制广播忽略此变量?”它可以通过我在下面提到的属性进行控制。由于没有人寻址,为了使其相关,我给出了这个迟来的答案。希望有帮助!请接受其中一个已接受的答案。它也将指向其他人。谢谢!这样做有意义吗当我想执行smallDF.join(广播(largeDF,“left\u outer”)时,使用(smallDF),“right\u outer”)?因为smallDF应该保存在内存中,而不是largeDFPls。下面提到了所有情况。在这里写入它不是一行的…将左外到右外的结果将改变。但是在正常情况下,表1左外连接表2,表2右外连接表1是相等的
Select /*+ MAPJOIN(b) */ a.key, a.value from a join b on a.key = b.key

hive> set hive.auto.convert.join=true;
hive> set hive.auto.convert.join.noconditionaltask.size=20971520
hive> set hive.auto.convert.join.noconditionaltask=true;
hive> set hive.auto.convert.join.use.nonstaged=true;
hive> set hive.mapjoin.smalltable.filesize = 30000000; // default 25 mb made it as 30mb
import org.apache.spark.sql.functions.broadcast  

val employeesDF = employeesRDD.toDF
val departmentsDF = departmentsRDD.toDF

// materializing the department data
val tmpDepartments = broadcast(departmentsDF.as("departments"))

import context.implicits._

employeesDF.join(broadcast(tmpDepartments), 
   $"depId" === $"id",  // join by employees.depID == departments.id 
   "inner").show()