一、SRC
问题:
- spark各部分代码分别在哪执行?
- 分布式程序中必然存在资源共享问题 ==》
分为2种,能互动的和不能互动的。broadcast variable和accumulator - 把1个task1个的副本变为1个executor1个
link
https://blog.csdn.net/Android_xue/article/details/79780463
note
- 不能将一个RDD使用广播变量广播出去,因为RDD是不存储数据的。可以将RDD的collect的结果广播出去。
- 广播变量只能在Driver端定义,不能在Executor端定义。
- 在executor修改变量,driver端的广播变量不会改变,如想改变==》累加器。
二、comprehending
1. bv
spark默认会把在executor中用到的driver中创建的变量序列化后发送到各个task中,如果task很多或者变量很大,就会出问题。
而bv会将变量发送到executor的BlockManager中,这样一个executor只会有一个。
bv只能读不能改,即使在executor改了,driver也不会同步
2. accumulator
accumulator在Driver端定义赋初始值,只能在Driver端读取最后的值,在Excutor端更新。
原理就是在driver设置初始值,然后在每个executor更新,然后driver把每个更新获取后再做一次累加。
比如在向bloomFilter添加数据时,就可以设置一个accu,然后在每个executor添加,最后在driver聚合。
三、usage
1. broadcast variable
val bv = sc.broadcast(list)
bv .value.contains(line)
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()
}
}
2. accumulator
object AccumulatorTest {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local").setAppName("accumulator")
val sc = new SparkContext(conf)
val accumulator = sc.accumulator(0); //创建accumulator并初始化为0
val linesRDD = sc.textFile("./word")
val result = linesRDD.map(s => {
accumulator.add(1) //有一条数据就增加1
s
})
result.collect();
println("words lines is :" + accumulator.value)
sc.stop()
}
}