Spark2.3(四十三):Spark Broadcast总结
为什么要使用广播(broadcast)变量?
Spark中因为算子中的真正逻辑是发送到Executor中去运行的,所以当Executor中需要引用外部变量时,需要使用广播变量。
进一步解释:
- 如果executor端用到了Driver的变量,如果不使用广播变量在Executor有多少task就有多少Driver端的变量副本。
- 如果Executor端用到了Driver的变量,如果使用广播变量在每个Executor中只有一份Driver端的变量副本。
Spark中Broadcast定义
官网定义:
A broadcast variable. Broadcast variables allow the programmer to keep a read-only variable cached on each machine rather than shipping a copy of it with tasks. They can be used, for example, to give every node a copy of a large input dataset in an efficient manner. Spark also attempts to distribute broadcast variables using efficient broadcast algorithms to reduce communication cost.
Broadcast variables are created from a variable v by calling SparkContext.broadcast(T, scala.reflect.ClassTag<T>). The broadcast variable is a wrapper around v, and its value can be accessed by calling the value method. The interpreter session below shows this:
[翻译]它是一个广播变量。广播变量允许程序员在每台计算机上缓存只读变量,而不是将其副本与任务一起发送。例如,它们可以有效地为每个节点提供一个大型输入数据集的副本。Spark还尝试使用有效的广播算法来分配广播变量,以降低通信成本。
广播变量是通过调用sparkcontext.broadcast(t,scala.reflect.classtag<t>)从变量v创建的。广播变量是围绕v的包装器,它的值可以通过调用value方法来访问。下面的口译员会话显示了这一点:
scala> val broadcastVar = sc.broadcast(Array(1, 2, 3))
broadcastVar: org.apache.spark.broadcast.Broadcast[Array[Int} = Broadcast(0) scala> broadcastVar.value
res0: Array[Int] = Array(1, 2, 3)
After the broadcast variable is created, it should be used instead of the value v in any functions run on the cluster so that v is not shipped to the nodes more than once. In addition, the object v should not be modified after it is broadcast in order to ensure that all nodes get the same value of the broadcast variable (e.g. if the variable is shipped to a new node later).
[翻译]创建广播变量后,应在集群上运行的任何函数中使用它,而不是使用值v,这样V就不会多次发送到节点。此外,对象v在广播后不应进行修改,以确保所有节点都获得广播变量的相同值(例如,如果变量稍后被发送到新节点)。
Broadcast.scala类定义:
package org.apache.spark.broadcast import java.io.Serializable import scala.reflect.ClassTag import org.apache.spark.SparkException
import org.apache.spark.internal.Logging
import org.apache.spark.util.Utils /**
* A broadcast variable.
* 。。。。。。
* @param id A unique identifier for the broadcast variable.
* @tparam T Type of the data contained in the broadcast variable.
*/
abstract class Broadcast[T: ClassTag](val id: Long) extends Serializable with Logging { /**
* Flag signifying whether the broadcast variable is valid(that is, not already destroyed) or not.
* 指示广播变量是否有效的标志(即,尚未销毁)或未销毁。
*/
@volatile private var _isValid = true private var _destroySite = "" /** Get the broadcasted value. */
def value: T = {
assertValid()
getValue()
} /**
* Asynchronously delete cached copies of this broadcast on the executors. If the broadcast is used after this is called, it will need to be re-sent to each executor.
* 异步删除执行器上此广播的缓存副本。如果在调用后使用广播,则需要将其重新发送给每个执行者。
*/
def unpersist() {
unpersist(blocking = false)
} /**
* Delete cached copies of this broadcast on the executors. If the broadcast is used after this is called, it will need to be re-sent to each executor.
* 删除执行器上此广播的缓存副本。如果在调用后使用广播,则需要将其重新发送给每个执行者。
* @param blocking Whether to block until unpersisting has completed 是否阻止直到unpersist完成
*/
def unpersist(blocking: Boolean) {
assertValid()
doUnpersist(blocking)
} /**
* Destroy all data and metadata related to this broadcast variable. Use this with caution; once a broadcast variable has been destroyed, it cannot be used again. This method blocks until destroy has completed
* 销毁与此广播变量相关的所有数据和元数据。小心使用;广播变量一旦被销毁,就不能再使用。此方法在销毁完成之前阻止
*/
def destroy() {
destroy(blocking = true)
} /**
* Destroy all data and metadata related to this broadcast variable. Use this with caution; once a broadcast variable has been destroyed, it cannot be used again.
* 销毁与此广播变量相关的所有数据和元数据。小心使用;广播变量一旦被销毁,就不能再使用。
* @param blocking Whether to block until destroy has completed 是否阻止直到销毁完成
*/
private[spark] def destroy(blocking: Boolean) {
assertValid()
_isValid = false
_destroySite = Utils.getCallSite().shortForm
logInfo("Destroying %s (from %s)".format(toString, _destroySite))
doDestroy(blocking)
} /**
* Whether this Broadcast is actually usable. This should be false once persisted state is removed from the driver.
* 广播变量是否实际可用。一旦持久化状态从driver中被移除将会返回false.
*/
private[spark] def isValid: Boolean = {
_isValid
} /**
* Actually get the broadcasted value. Concrete implementations of Broadcast class must define their own way to get the value.
* 实际获取广播值。广播类的具体实现必须定义自己的方法来获取值。
*/
protected def getValue(): T /**
* Actually unpersist the broadcasted value on the executors. Concrete implementations of Broadcast class must define their own logic to unpersist their own data.
*/
protected def doUnpersist(blocking: Boolean) /**
* Actually destroy all data and metadata related to this broadcast variable. Implementation of Broadcast class must define their own logic to destroy their own state.
*/
protected def doDestroy(blocking: Boolean) /** Check if this broadcast is valid. If not valid, exception is thrown. */
protected def assertValid() {
if (!_isValid) {
throw new SparkException("Attempted to use %s after it was destroyed (%s) ".format(toString, _destroySite))
}
} override def toString: String = "Broadcast(" + id + ")"
}
其中隐含的概念:
1)broadcast的定义必须在Driver端,不能再executor端定义;
2)调用unpersist(),unpersist(boolean blocking),destroy(),distroy(boolean blocking)方法这些方法必须在driver端调用。
3)在Driver端可以修改广播变量的值,在Executor端无法修改广播变量的值。具体操作步骤:
a.在driver端调用unpersist(true)方法;
b.对该broadcast实例对象进行重新赋值。
参考《Spark2.2(三十三):Spark Streaming和Spark Structured Streaming更新broadcast总结(一)》、《Spark2.3(四十二):Spark Streaming和Spark Structured Streaming更新broadcast总结(二)》
Broadcast工作流程
Broadcast使用时注意事项
注意事项
1、能不能将一个RDD使用广播变量广播出去?
不能,因为RDD是不存储数据的。可以将RDD的结果广播出去。
2、广播变量只能在Driver端定义,不能在Executor端定义。
3、在Driver端可以修改广播变量的值,在Executor端无法修改广播变量的值。
4、如果executor端用到了Driver的变量,如果不使用广播变量在Executor有多少task就有多少Driver端的变量副本。
5、如果Executor端用到了Driver的变量,如果使用广播变量在每个Executor中只有一份Driver端的变量副本。
Spark2.3(四十三):Spark Broadcast总结的更多相关文章
- Spark(四) -- Spark工作机制
一.应用执行机制 一个应用的生命周期即,用户提交自定义的作业之后,Spark框架进行处理的一系列过程. 在这个过程中,不同的时间段里,应用会被拆分为不同的形态来执行. 1.应用执行过程中的基本组件和形 ...
- (四)Spark集群搭建-Java&Python版Spark
Spark集群搭建 视频教程 1.优酷 2.YouTube 安装scala环境 下载地址http://www.scala-lang.org/download/ 上传scala-2.10.5.tgz到m ...
- NeHe OpenGL教程 第四十三课:FreeType库
转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...
- [Spark內核] 第42课:Spark Broadcast内幕解密:Broadcast运行机制彻底解密、Broadcast源码解析、Broadcast最佳实践
本课主题 Broadcast 运行原理图 Broadcast 源码解析 Broadcast 运行原理图 Broadcast 就是将数据从一个节点发送到其他的节点上; 例如 Driver 上有一张表,而 ...
- Java进阶(四十三)线程与进程的区别
Java进阶(四十三)线程与进程的区别 1.线程的基本概念 概念:线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必 ...
- 网站开发进阶(四十三)html中,路径前加“/” 与不加“/”的区别
网站开发进阶(四十三)html中,路径前加"/" 与不加"/"的区别 前言 <script src="js/downloadify.js&quo ...
- Gradle 1.12用户指南翻译——第四十三章. 构建公告插件
本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...
- “全栈2019”Java第四十三章:封装
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- Spark Broadcast内幕解密:Broadcast运行机制彻底解密、Broadcast源码解析、Broadcast最佳实践
本课主题 Broadcast 运行原理图 Broadcast 源码解析 Broadcast 运行原理图 Broadcast 就是将数据从一个节点发送到其他的节点上; 例如 Driver 上有一张表,而 ...
随机推荐
- Python 面向对象1-面向对象介绍
一.无论用什么形式来编程,我们都要明确记住以下原则: 1.写重复代码是非常不好的低级行为 2.你写的代码需要经常变更,写代码一定要遵循易读,易改的原则 3.函数编程与OOP(面向对象)的主要区别就是O ...
- django-admin 仿写stark组件action,filter筛选过滤,search查询
写在StandLi里面的方法都是通过ModelSubject这个类里面的stand_li方法,在它里面用StandLi这个类实例化出来一个对象,这个实例化出来的对象把数据传给前端HTML模板进行渲染, ...
- java读写excel文件( POI解析Excel)
package com.zhx.base.utils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi ...
- HDU 3966 Aragorn's Story(模板题)【树链剖分】+【线段树】
<题目链接> 题目大意: 给定一颗带点权的树,进行两种操作,一是给定树上一段路径,对其上每个点的点权增加或者减少一个数,二是对某个编号点的点权进行查询. 解题分析: 树链剖分的模板题,还不 ...
- 从小白到区块链工程师:第一阶段:Go语言的控制台输入和输出(3)
六,Print系列的函数输出 1:Println 打印换行.Print控制台打印,lnline 一行,打印数据后自动换一行显示.下面显示在控制台打印出不同的类型. 打印输出结果后,会自动换一行.打印结 ...
- Looping through the content of a file in Bash
https://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash One way to ...
- C# SQLiteHelper
using System; using System.Data; using System.Data.Common; using System.Data.SQLite; using System.IO ...
- Xamarin Essentials教程使用加速度传感器Accelerometer
Xamarin Essentials教程使用加速度传感器Accelerometer 加速度传感器是一种能够测量加速度的传感器,用于检测设备状态的改变.在Xamarin中,如果开发者想要使用加速度传 ...
- 给有C或C++基础的Python入门 :Python Crash Course 4 操作列表 4.4 -- 4.5
上接前一篇文章. 4.4 使用列表的一部分 一,切片 切边,顾名思义,就是处理列表的部分元素. 我们可以联系一下C++的一段语句:for(int i = 0; i < n-2; ++i) cou ...
- BZOJ.1568.[JSOI2008]Blue Mary开公司(李超线段树)
题目链接 线段树每个节点记录\(f(mid)\)最大的直线(在\(mid\)处函数值最大的直线),称作优势线段(还是直线啊...无所谓了). 如果是在区间插入线段会影响\(O(\log n)\)个区间 ...