是否需要在Spark中广播对象成员?

时间:2019-03-26 09:54:03

标签: apache-spark broadcast

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

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

2 个答案:

答案 0 :(得分:2)

在这种情况下

rdd.map(arr.contains(_))

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

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

每个执行者只能执行一次。

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

答案 1 :(得分:2)

除了拉斐尔的答案之外,还有两点需要提及,这是正确的。您必须始终考虑广播的变量的大小,这个大小不能太大,否则Spark将难以在整个集群中有效分配它。您的情况是:

4B x 1000000 = 4000000B ~ 4GB

已超过默认值4MB,可以通过修改spark.broadcast.blockSize的{​​{3}}进行控制。

决定是否使用广播的另一个因素是何时拥有value并希望避免改组。通过广播数据帧,密钥将立即在节点中可用,因此避免了从不同节点检索数据(改组)。