Spark—三大数据结构之广播变量

Spark—三大数据结构之广播变量

本文记录了Spark三大数据结构中广播变量的相关知识



前言

Spark 计算框架为了能够进行高并发和高吞吐的数据处理,封装了三大数据结构,用于
处理不同的应用场景。三大数据结构分别是:

  1. RDD : 弹性分布式数据集
  2. 累加器:分布式共享只写变量
  3. 广播变量:分布式共享只读变量

提示:以下是本篇文章正文内容

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封装成广播变量,功能也是可以实现,但实际应用中处理的是大数据,使用广播变量能更好的提升性能(以刚刚的例子进行分析):

  1. 在Driver端生成的数据map,发送给Executor端时,会进行闭包检测,形成闭包数据,以Task为单位发送,也就是说每个任务中包含闭包数据
  2. 一般情况下,假设Driver端有8个分区,那么就会有相应的8个Task,此时每个Task都会用到闭包数据map
  3. 当Task被提交到Executor之后,假设只有一个Executor资源,那么8个Task进行的是并发操作,并且每个Task中包含map数据,如果map的数据量非常大,但每个Task中都包含,此时会降低性能,而且会数据冗余,因为在同一个Executor中有8个Task任务的map数据,这样可能会导致,一个Executor中含有大量重复的数据,并且占用大量的内存
  4. 而在Spark中,每个Executor其实就一个JVM,所以在启动时,会自动分配内存,所以完全可以将任务中的闭包数据放置在Executor的内存中,达到共享的目的
  5. Spark中的广播变量就可以将闭包的数据保存到Executor的内存中
  6. 但要注意的是:Spark中的广播变量不能够更改,因为一旦广播变量更改,那么相对应需要用到广播变量的Task中的数据也要更改,这也是为什么广播变量被称为分布式共享只读变量

总结

文章也是仅作知识点的记录,欢迎大家指出错误,如有新的感悟也会一并更新,一起探讨~~~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值