一、使用场景
如果我们要在分布式计算里面分发大对象(如:字典,集合,黑白名单等),由Driver端进行分发。如果这个变量不是广播变量,那么每个Task就会分发一份,如果Task数目较多的情况下,Driver的带宽会成为系统的瓶颈且会大量消耗Task所在的Executor服务器的内存资源。
如果将这个变量声明为广播变量,那么只是每个Executor分发一份,该Executor启动的所有Task都可共享这个变量,节省了网络带宽的成本和服务器的内存资源。
对比效果图如下:
使用广播变量
二、注意事项
1、广播变量只能在Driver端定义,不能在Executor端定义
2、广播变量只能在Driver端修改,不能在Executor端修改
3、广播变量在每个Executor中只有一份Driver端的变量副本
4、RDD无法作为广播变量,因为RDD是逻辑对象、不存储数据
三、使用方式
1、通过对一个类型 T 的对象调用 SparkContext.broadcast 创建出一个 Broadcast[T] 对象。任何可序列化的类型都可以这么实现。
2、通过 value 属性访问该对象的值(在 Java 中为 value() 方法)。
3、变量只会被发到各个节点一次,应作为只读值处理(修改这个值不会影响到别的节点)。
示例代码如下:
object BroadcastTest {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local").setAppName("broadcast")
val sc = new SparkContext(conf)
val list = List("hello java")
val broadcast = sc.broadcast(list)
val linesRDD = sc.textFile("./word")
linesRDD.filter(line => {
broadcast.value.contains(line)
}).foreach(println)
sc.stop()
}
}
网友评论