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.blockSize
的value来控制。
决定是否使用广播的另一个因素是当您有 joins 并且想要避免随机播放时。通过广播数据帧,密钥将立即在节点中可用,从而避免从不同节点检索数据(混洗)。
假设我有一个对象,我需要对该对象的成员进行一些操作: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.blockSize
的value来控制。
决定是否使用广播的另一个因素是当您有 joins 并且想要避免随机播放时。通过广播数据帧,密钥将立即在节点中可用,从而避免从不同节点检索数据(混洗)。