本书及作者信息
作者: 余辉
微信公众号:辉哥大数据
备注:本书配套示例源码、PPT课件、教学视频与作者答疑服务,每周更新一部分,敬请期待…
红包奖励:找出本书问题,评论区并指正,且留下联系方式
本书其他章节
- Spark大数据开发与应用案例(视频教学版)(一)–文前
- Spark大数据开发与应用案例(视频教学版)(二)–第一章上
- Spark大数据开发与应用案例(视频教学版)(三)–第一章下
- Spark大数据开发与应用案例(视频教学版)(四)–第二章上
- Spark大数据开发与应用案例(视频教学版)(五)–第二章下
- Spark大数据开发与应用案例(视频教学版)(六)–第三章上
- Spark大数据开发与应用案例(视频教学版)(七)–第三章下
- Spark大数据开发与应用案例(视频教学版)(八)–第四章上
- Spark大数据开发与应用案例(视频教学版)(九)–第四章下
- Spark大数据开发与应用案例(视频教学版)(十)–第五章
第6章 Spark共享变量
本章将带你深入探索Spark中的两大重要分布式共享变量——广播变量与累加器。通过详细解读它们的定义、用途及工作原理,助你高效处理大规模数据。最后,对本章内容进行总结,巩固学习成果。
本章主要知识点:
- 广播变量
- 累加器
6.1 广播变量
在Apache Spark中,广播变量(Broadcast Variables)是一种非常有用的优化技术,它们允许程序员将一个只读变量缓存到每个工作节点的内存中,而不是在每个任务中重新发送这个变量。这样做可以显著减少网络通信开销,并提高Spark程序的运行效率,尤其是在变量体积较大且需要跨多个任务访问时。
6.1.1 广播变量的使用场景
在很多计算场景,经常会遇到两个RDD进行join,如果一个RDD对应的数据比较大,一个RDD对应的数据比较小,这种情况下使用join,肯定会shuffle从而导致效率变低。广播变量就是将相对较小的数据先收集到Driver,然后再通过网络广播到属于该Application对应的每个Executor中,以后处理大量数据对应的RDD关联数据就不用shuffle了,而是直接在内存中关联已经广播好的数据。即通过实现mapside join,将Driver端的数据广播到属于该application的Executor,然后通过Driver广播变量返回的引用,获取实现广播到Executor的数据。
广播变量的特点是:广播出去的数据就无法再改变了,在每个Executor中是只读的操作,在每个Executor中多个Task使用一份广播变量。
广播变量的执行步骤(见图6-1)可以总结如下:
(1)准备数据:确定需要广播的数据,这些数据通常相对较小,且需要在多个Executor之间共享。这些数据必须在Driver端准备完毕。
(2)通过BroadcastManager管理:在Driver端,使用BroadcastManager来管理要广播的数据。BroadcastManager负责将数据打包并准备进行广播。
(3)广播数据:Driver端通过网络将数据以比特流的方式发送到属于该Application的每个Executor中。这个过程是由BroadcastManager协调完成的,确保数据能够高效地传输到每个Executor。
(4)Executor接收数据:每个Executor接收到广播的数据后,会将其存储在本地内存中.这些数据在Executor中是只读的,且每个Executor中多个Task共享一份广播变量。
(5)Task执行时使用广播变量:当Task需要访问广播变量中的数据时,它会通过Driver广播变量返回的引用来获取这些数据。由于数据已经广播到每个Executor中,因此Task可以直接在本地内存中访问这些数据,而无须进行shuffle操作。
(6)提高效率:通过使用广播变量,可以避免在RDD JOIN等操作中进行不必要的shuffle操作。这可以显著提高数据处理的效率,减少网络通信的时间开销。
综上所述,广播变量的执行步骤包括准备数据、通过BroadcastManager管理、广播数据、Executor接收数据、Task执行时使用广播变量以及提高效率等关键步骤。这些步骤共同确保了广播变量能够在分布式计算框架中高效地工作。
6.1.2 广播变量的实现原理
广播变量是通过Spark的内部通信机制来分发的,多个Executor可以相互传递数据,可以提高效率。sc.broadcast这个方法是阻塞的(同步的)。
广播变量一但广播出去就不能改变,为了以后可以定期地改变要关联的数据,可以定义一个object[单例对象]在函数内使用,并且加一个定时器,然后定期更新数据。
广播到Executor的数据,可以在Driver获取到引用,这个引用会伴随着每一个Task发送到Executor,然后通过这个引用获取到事先广播好的数据。
6.1.3 案例:两个集合进行结合
- 需求说明
在满足两个集合进行结合情况下,本案例还会满足下面三点要求:
- 不使用广播变量,使用join算子,有Shuffle。
- 不使用广播变量,使用map函数和模式匹配,没有Shuffle。
- 使用广播变量,使用map函数和模式匹配,没有Shuffle。
- 代码实现
两个集合进行join,示例代码如代码6-1所示。
代码6-1 Broadcast01.scala
package chapter06
/**
* author: yuhui
* date: 2024 - 11 - 03 8:50 上午
* descriptions: 广播变量
* 1)不使用广播变量,使用join算子,有Shuffle
* 2)不使用广播变量,使用map函数和模式匹配,没有Shuffle
* 3)使用广播变量,使用map函数和模式匹配,没有Shuffle
*
* 运行结果
* (a,(1,4))
* (b,(2,5))
* (c,(3,6))
* (d,(4,7))
*/
import org.apache.spark.broadcast.Broadcast
import org.apache.spark.rdd.RDD
import org.apache.spark.{
SparkConf, SparkContext}
import scala.collection.mutable
object Broadcast01 {
def main(args: Array[String]): Unit = {
val conf: SparkConf = new SparkConf().setMaster("local[4]").setAppName("BroadcastDemo")
val sc: SparkContext = new SparkContext(conf)
val rdd: RDD[(String, Int)] = sc.makeRDD(List(("a",