繁体   English   中英

仅使用 Spark-SQL API 时广播变量的使用

[英]Usage of Broadcast Variables when using only Spark-SQL API

在使用 Spark-RDD API 时,我们可以使用广播变量来优化 Spark 分发不可变状态的方式。

1) 广播变量如何在内部工作?

我的假设是:对于用于对数据集执行操作的每个闭包,所有它引用的变量都必须被序列化、通过网络传输并与任务一起恢复,以便闭包可以被执行。

当注册这样的广播变量时​​:

val broadcastVar = sc.broadcast("hello world")

返回的对象( Broadcast[String] )不保留对实际对象(“hello world”)的引用,而只保留一些 ID。 当一个广播变量句柄从上面所说的闭包中被引用时,它将像其他所有变量一样被序列化 - 只是广播变量句柄本身不包含实际对象。

当闭包稍后在目标节点上执行时,实际对象(“hello world”)已经转移到每个节点。 当闭包到达调用broadcastVar.value的点时, broadcastVar.value变量句柄在内部使用 ID 检索实际对象。

这个假设正确吗?

2) 有没有办法在 Spark-SQL 中利用这种机制?

假设我有一组允许的值。

使用 RDD-API 时,我将为我的 allowedValues 创建一个广播变量:

val broadcastAllowedValues = sc.broadcast(allowedValues) // Broadcast[Set[String]]

rdd.filter(row => broadcastAllowedValues.value.contains(row("mycol")))

当然,当使用 Spark-SQL-API 时,我会使用Column.isin / Column.isInCollection方法:

dataframe.where(col("mycol").isInCollection(allowedValues))

但似乎我无法通过这种方式获得广播变量的优势。

另外,如果我将这段代码更改为以下内容:

val broadcastAllowedValues = sc.broadcast(allowedValues) // Broadcast[Set[String]]

dataframe.where(col("mycol").isInCollection(allowedValues.value))

这部分:

col("mycol").isInCollection(allowedValues.value)
// and more important this part:
allowedValues.value

将已经在驱动程序上进行评估,从而产生一个新的Column -Object。 所以广播变量在这里失去了它的优势。 与第一个示例相比,它甚至会有一些开销......

有没有办法使用 Spark-SQL-API 来利用广播变量,或者我是否必须在这些点显式使用 RDD-API?

广播变量如何在内部工作?

广播的数据被序列化并物理移动到所有执行器。 根据关于Broadcast Variables的文档,它说

“广播变量允许程序员在每台机器上缓存一个只读变量,而不是随任务一起传送它的副本。”

有没有办法在 Spark-SQL 中利用这种机制?

是的,有一种方法可以利用优势。 Spark 在加入大小数据帧时默认应用广播哈希加入

根据“Learning Spark - 2nd edition”一书,它说:

“默认情况下,如果较小的数据集小于 10MB,Spark 将使用广播连接。此配置在spark.sql.autoBroadcastJoinThreshold设置;您可以根据每个执行程序和在司机。”

你的情况,你需要列出所有独特ALLOWEDVALUES成简单的数据帧(数据帧称为allowedeValuesDF )只有一列(列名为allowValues )和应用加入到过滤您的dataframe

像这样的东西:

import org.apache.spark.sql.functions.broadcast
val result = dataframe.join(broadcast(allowedValuesDF), "mycol === allowedValues")

实际上,您可以省略broadcast因为默认情况下 Spark 会执行广播连接。

编辑:

在更高版本的 Spark 中,您还可以在 SQL 语法中使用连接提示来告诉执行引擎使用哪些策略。 SQL 文档中提供了详细信息,下面提供了一个示例:

-- Join Hints for broadcast join 
SELECT /*+ BROADCAST(t1) */ * FROM t1 INNER JOIN t2 ON t1.key = t2.key;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM