Spark中有必要广播一个对象成员吗?

Is it necessary to broadcast an object member in Spark?

假设我有一个对象,我需要对该对象的成员进行一些操作: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中的节点进行传递。

这种场景有必要使用广播吗?

案例

rdd.map(arr.contains(_))

arr 为每个任务序列化发货

同时在

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

每个执行者只执行一次。

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

除了 Raphael 的正确回答之外,还有两件事要提。您必须始终考虑您广播的变量的大小不应该太大,否则 Spark 将难以在集群中有效地分发它。你的情况是:

4B x 1000000 = 4000000B ~ 4GB

已经超过了默认值4MB,可以通过修改spark.broadcast.blockSizevalue来控制。

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