为什么要用broadcast?

If you have huge array that is accessed from Spark Closures, for example some reference data, this array will be shipped to each spark node with closure. For example if you have 10 nodes cluster with 100 partitions (10 partitions per node), this Array will be distributed at least 100 times (10 times to each node).

If you use broadcast it will be distributed once per node using efficient p2p protocol.

val array: Array[Int] = ??? // some huge array
val broadcasted = sc.broadcast(array)

And some RDD

val rdd: RDD[Int] = ???

In this case array will be shipped with closure each time

rdd.map(i => array.contains(i))

and with broadcast you'll get huge performance benefit

rdd.map(i => broadcasted.value.contains(i))

变量不broadcast仅仅影响的是效率吗?

理解闭包
      Spark中理解起来比较困难的一点是当代码在集群上运行时变量和方法的生命周期和作用域(scope)。当作用于RDD上的操作修改了超出它们作用域范围的变量时,会引起一些混淆。为了说明这个问题,使用下面的例子。该例中使用foreach(),对counter(计数器)进行增加,相同的问题也会发生在其他操作中。

 

例子

下面的例子在以本地模式运行(--master = local[n]) 和将它部署到集群中 (例如通过 spark-submit 提交到 YARN)对比发现会产生不同的结果。

1
2
3
4
5
 
var counter = 0
var rdd = sc.parallelize(data)
// 错误,请不要这样做!!
rdd.foreach(x => counter += x)
println("Counter value: " + counter)

本地模式 vs. 集群模式

这里主要的挑战是上面代码的行为是有歧义的。以本地模式运行在单个JVM上,上面的代码会将RDD中的值进行累加,并且将它存储到counter中。这是因为RDD和变量counter在driver节点的相同内存空间中。
      然而,以集群模式运行时,会更加复杂,上面的代码的结果也许不会如我们预期的那样。当执行一个作业(job)时,Spark会将RDD分成多个任务(task)--每一个任务都会由一个executor来执行。在执行之前,Spark会计算闭包(closure)。闭包是对executors可见的那部分变量和方法,executors会用闭包来执行RDD上的计算(在这个例子中,闭包是foreach())。这个闭包是被序列化的,并且发送给每个executor。在本地模式中,只有一个executor,所以共享相同的闭包。然而,在集群模式中,就不是这样了。executors会运行在各自的worker节点中,每个executor都有闭包的一个复本。
      发送给每个executor的闭包中的变量其实也是复本。每个foreach函数中引用的counter不再是driver节点上的counter。当然,在driver节点的内存中仍然存在这一个counter,但是这个counter对于executors来说是不可见的。executors只能看到自己的闭包中的复本。这样,counter最后的值仍旧是0,因为所有在counter的操作只引用了序列化闭包中的值。
      为了在这样的场景中,确保这些行为正确,应该使用累加变量(Accumulator)。在集群中跨节点工作时,Spark中的累加变量提供了一种安全的机制来更新变量。所以可变的全局状态应该使用累加变量来定义。

所以上面的例子可以这样写:

1
2
3
4
5
 
// counter现在是累加变量
var counter = sc.accumulator(0)
var rdd = sc.parallelize(data)
rdd.foreach(x => counter += x)
println("Counter value: " + counter)

spark 为什么要用broadcast[转]的更多相关文章

  1. 【Spark调优】Broadcast广播变量

    [业务场景] 在Spark的统计开发过程中,肯定会遇到类似小维表join大业务表的场景,或者需要在算子函数中使用外部变量的场景(尤其是大变量,比如100M以上的大集合),那么此时应该使用Spark的广 ...

  2. Spark2.2(三十三):Spark Streaming和Spark Structured Streaming更新broadcast总结(一)

    背景: 需要在spark2.2.0更新broadcast中的内容,网上也搜索了不少文章,都在讲解spark streaming中如何更新,但没有spark structured streaming更新 ...

  3. Spark2.3(四十二):Spark Streaming和Spark Structured Streaming更新broadcast总结(二)

    本次此时是在SPARK2,3 structured streaming下测试,不过这种方案,在spark2.2 structured streaming下应该也可行(请自行测试).以下是我测试结果: ...

  4. 【Spark Java API】broadcast、accumulator

    转载自:http://www.jianshu.com/p/082ef79c63c1 broadcast 官方文档描述: Broadcast a read-only variable to the cl ...

  5. Spark2.3(四十三):Spark Broadcast总结

    为什么要使用广播(broadcast)变量? Spark中因为算子中的真正逻辑是发送到Executor中去运行的,所以当Executor中需要引用外部变量时,需要使用广播变量.进一步解释: 如果exe ...

  6. spark 源码分析之十四 -- broadcast 是如何实现的?

    本篇文章主要剖析broadcast 的实现机制. BroadcastManager初始化 BroadcastManager初始化方法源码如下: TorrentBroadcastFactory的继承关系 ...

  7. Spark性能调优:广播大变量broadcast

    Spark性能调优:广播大变量broadcast 原文链接:https://blog.csdn.net/leen0304/article/details/78720838 概要 有时在开发过程中,会遇 ...

  8. 【转载】 Spark性能优化指南——基础篇

    转自:http://tech.meituan.com/spark-tuning-basic.html?from=timeline 前言 开发调优 调优概述 原则一:避免创建重复的RDD 原则二:尽可能 ...

  9. 【转】Spark性能优化指南——基础篇

    http://mp.weixin.qq.com/s?__biz=MjM5NDMwNjMzNA==&mid=2651805828&idx=1&sn=2f413828d1fdc6a ...

随机推荐

  1. smartforms设置表格脚标在最后一页显示

    用户打印采购订单时,末尾计算一个合计金额,但是有多页时,合计显示在了每一页,现在希望合计项只显示在表格最后一行就可以. smartforms调整表格,将总计放在脚标内,设置脚标输出打印[在表结束处]即 ...

  2. 解决Fail to post notification on channel "null"的方法

    mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);mNotifyMgr.cancelAll(); St ...

  3. 机器学习算法——kNN

    顶级数据挖掘会议ICDM于2006年12月评选出了数据挖掘领域的十大经典算法,kNN便是其中一个. kNN算法的思想是:在训练集中选取与输入数据最近的k个邻居,统计k个邻居中出现次数最多的类别,以此作 ...

  4. PHPJN0001:phpmyadmin 允许密码为空 设置

    phpmyadmin连接mysql数据库,出于安全考虑,默认不允许使用空密码连接数据库.因为数据库一般都设置密码访问. 但如果只是本机环境测试使用,每隔一段时间都需要填写密码,不是很方便. 如果没有修 ...

  5. #《Essential C++》读书笔记# 第一章 C++ 编程基础

    前言 Stanley B.Lippman 先生所著的<C++ Primer>是学习C++的一本非常优秀的教科书,但<C++ Primer>作为一本大部头书,显然不适合所有的初学 ...

  6. 《自拍教程21》mediainfo_多媒体文件查看工具

    mediainfo命令介绍 mediainfo.exe(Linux/iMac下是未带后缀的mediainfo), 是一款音视频图片文件的信息查询工具, 常用于查看多媒体文件的视频流信息,音频流信息,字 ...

  7. P2214 [USACO14MAR]哞哞哞Mooo Moo

    链接:Miku ---------------------- 这道题还是个背包 --------------------- 首先看一下声音的组成,对于每一个农场的声音,它是由两部分组成的 :上一个农场 ...

  8. Uderstanding and using Pointers 读书笔记

    如何阅读指针? 从右向左读. 比如 const int *pci; 虚拟内存和虚拟内存地址是什么? 一个应用程序,在虚拟内存地址里也许是连续的,但是在物理内存里也许是分隔开来的. 虚拟内存和物理内存的 ...

  9. python变量加逗号,的含义

    逗号,用于生成一个长度为1的元组 >>> (1) 1 >>> (1,) (1,) >>> 1, (1,) 因此需要将长度为1的元组中元素提取出来可 ...

  10. Neo4j入门-开始使用

    前言 关系,指事物之间相互作用.相互影响的状态. 数据之间的关系也是如此,数据之间关系的存储在RDS就已经开始.从数据库支持的外键,到手动建立的关系表,人们采取了许多方法,只为了解决查询复杂.缓慢等问 ...