[英]Usage of Broadcast Variables when using only Spark-SQL API
在使用 Spark-RDD API 时,我们可以使用广播变量来优化 Spark 分发不可变状态的方式。
我的假设是:对于用于对数据集执行操作的每个闭包,所有它引用的变量都必须被序列化、通过网络传输并与任务一起恢复,以便闭包可以被执行。
当注册这样的广播变量时:
val broadcastVar = sc.broadcast("hello world")
返回的对象( Broadcast[String]
)不保留对实际对象(“hello world”)的引用,而只保留一些 ID。 当一个广播变量句柄从上面所说的闭包中被引用时,它将像其他所有变量一样被序列化 - 只是广播变量句柄本身不包含实际对象。
当闭包稍后在目标节点上执行时,实际对象(“hello world”)已经转移到每个节点。 当闭包到达调用broadcastVar.value
的点时, broadcastVar.value
变量句柄在内部使用 ID 检索实际对象。
这个假设正确吗?
假设我有一组允许的值。
使用 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.