Spark—三大数据结构之广播变量
本文记录了Spark三大数据结构中广播变量的相关知识
前言
Spark 计算框架为了能够进行高并发和高吞吐的数据处理,封装了三大数据结构,用于
处理不同的应用场景。三大数据结构分别是:
- RDD : 弹性分布式数据集
- 累加器:分布式共享只写变量
- 广播变量:分布式共享只读变量
提示:以下是本篇文章正文内容
1、实现原理
广播变量用来高效分发较大的对象。向所有工作节点发送一个较大的只读值,以供一个或多个 Spark 操作使用。比如,如果你的应用需要向所有节点发送一个较大的只读查询表,广播变量用起来都很顺手。在多个并行操作中使用同一个变量,但是 Spark 会为每个任务分别发送。
2、广播变量的使用
以下代码功能为: 实现相同Key的Value进行链接
代码如下(示例):
val sparConf = new SparkConf().setMaster("local").setAppName("Acc")
val sc = new SparkContext(sparConf)
val rdd = sc.makeRDD(List(
("a", 1),("b", 2),("c", 3),("d",4),("a", 8)
))
val map = mutable.Map(("a", 4),("b", 5),("c", 6),("e",7))
// 封装广播变量
val bc: Broadcast[mutable.Map[String, Int]] = sc.broadcast(map)
rdd.map {
// rdd中的(k,v)
case (w, c) => {
// 方法广播变量
val l: Int = bc.value.getOrElse(w, 0) // // 获取广播变量中的Value
(w, (c, l)) // 预期数据的格式
}
}.collect().foreach(println)
sc.stop()
结果:
因为 ‘e’ 没有在rdd中匹配到,所以不会出现在结果集中
(a,(1,4))
(b,(2,5))
(c,(3,6))
(d,(4,0))
(a,(8,4))
3. 为什么使用广播变量
上面例子实现相同Key的Value进行链接,用转换算子join也能实现 Spark—常用的RDD转换算子,但使用join算子,如果两个数据源中key有多个相同的,会依次匹配,可能会出现笛卡尔乘积,数据量会几何性增长,会导致性能降低;
当然,也可以直接使用map进行数据格式的转换,因为原始的数据是(“a”,1),预期结果是(“a”,(1,4)),那么只需使用map返回所需的格式即可
val rdd = sc.makeRDD(List(
("a", 1),("b", 2),("c", 3),("d",4),("a", 8)
))
val map = mutable.Map(("a", 4),("b", 5),("c", 6),("e",7))
rdd.map {
// rdd中的(k,v)
case (w, c) => {
val l: Int = map.getOrElse(w, 0) // 获取map的Value
(w, (c, l)) // ("a",(1,4))
}
}.collect().foreach(println)
此时只是没有把map封装成广播变量,功能也是可以实现,但实际应用中处理的是大数据,使用广播变量能更好的提升性能(以刚刚的例子进行分析):
- 在Driver端生成的数据map,发送给Executor端时,会进行闭包检测,形成闭包数据,
以Task为单位发送
,也就是说每个任务中包含闭包数据 - 一般情况下,假设Driver端有8个分区,那么就会有相应的8个Task,此时每个Task都会用到闭包数据map
- 当Task被提交到Executor之后,假设
只有一个Executor资源
,那么8个Task进行的是并发操作,并且每个Task中包含map数据,如果map的数据量非常大,但每个Task中都包含,此时会降低性能,而且会数据冗余,因为在同一个Executor中有8个Task任务的map数据
,这样可能会导致,一个Executor中含有大量重复的数据,并且占用大量的内存 - 而在Spark中,
每个Executor其实就一个JVM
,所以在启动时,会自动分配内存
,所以完全可以将任务中的闭包数据放置在Executor的内存中
,达到共享的目的 - Spark中的
广播变量就可以将闭包的数据保存到Executor的内存中
- 但要注意的是:Spark中的广播变量
不能够更改
,因为一旦广播变量更改,那么相对应需要用到广播变量的Task中的数据也要更改,这也是为什么广播变量被称为分布式共享只读变量
总结
文章也是仅作知识点的记录,欢迎大家指出错误,如有新的感悟也会一并更新,一起探讨~~~