是否有必要在Spark中广播一个对象成员?

问题描述 投票:0回答:2

假设我有一个对象,我需要对该对象的成员进行一些操作:arr

object A {
  val arr = (0 to 1000000).toList
  def main(args: Array[String]): Unit = {
    //...init spark context
    val rdd: RDD[Int] = ...
    rdd.map(arr.contains(_)).saveAsTextFile...
  }
}

广播的arr和没有广播的有什么区别?即

val arrBr = sc.broadcast(arr)
rdd.map(arrBr.value.contains(_))

rdd.map(arr.contains(_))

在我看来,对象A是一个单例对象,因此它将通过Spark中的节点传输。

在这种情况下是否有必要使用广播?

apache-spark broadcast
2个回答
2
投票

在这种情况下

rdd.map(arr.contains(_))

arr针对每项任务进行了序列化

而在

val arrBr = sc.broadcast(arr)
rdd.map(arrBr.value.contains(_))

这只是每个遗嘱执行人一次。

因此,在处理大型数据结构时应使用广播。


2
投票

拉斐尔的答案旁边还有两件事要提,这是正确的。您必须始终考虑广播的变量的大小,这不应该太大,否则Spark将难以在群集中有效地分发它。在你的情况下是:

4B x 1000000 = 4000000B ~ 4GB

它已超过默认值4MB,可以通过修改valuespark.broadcast.blockSize来控制。

决定是否使用广播的另一个因素是你有joins并且想要避免改组。通过广播数据帧,密钥将立即在节点中可用,因此避免从不同节点检索数据(混洗)。

© www.soinside.com 2019 - 2024. All rights reserved.