spark学习-25-Spark广播变量与共享变量(1)

来源:互联网 发布:linux 复制文件夹命令 编辑:程序博客网 时间:2024/06/11 10:32

1,概念

1.1 广播变量:

广播变量允许程序员将一个只读的变量缓存在每台机器上,而不用在任务之间传递变量。广播变量可被用于有效地给每个节点一个大输入数据集的副本。Spark还尝试使用高效地广播算法来分发变量,进而减少通信的开销。 Spark的动作通过一系列的步骤执行,这些步骤由分布式的洗牌操作分开。Spark自动地广播每个步骤每个任务需要的通用数据。这些广播数据被序列化地缓存,在运行任务之前被反序列化出来。这意味着当我们需要在多个阶段的任务之间使用相同的数据,或者以反序列化形式缓存数据是十分重要的时候,显式地创建广播变量才有用。

1.2 累加器:

累加器是仅仅被相关操作累加的变量,因此可以在并行中被有效地支持。它可以被用来实现计数器和总和。Spark原生地只支持数字类型的累加器,编程者可以添加新类型的支持。如果创建累加器时指定了名字,可以在Spark的UI界面看到。这有利于理解每个执行阶段的进程。(对于python还不支持) 累加器通过对一个初始化了的变量v调用SparkContext.accumulator(v)来创建。在集群上运行的任务可以通过add或者”+=”方法在累加器上进行累加操作。但是,它们不能读取它的值。只有驱动程序能够读取它的值,通过累加器的value方法。

2。广播变量使用方法广播变量

共享变量分为:Broadcast Variable(广播变量) 和 Accumulator(累加器)
广播变量:
- 添加广播变量 sc.broadcast(参数)
- 获取值要 名.value

很简单其实就是SparkContext的broadcast()方法,传入你要广播的变量,即可

final Broadcast<Map<String, Map<String, IntList>>> broadcast = sc.broadcast(fastutilDateHourExtractMap);

使用广播变量的时候,直接调用广播变量(Broadcast类型)的value() / getValue() ,可以获取到之前封装的广播变量

Map<String, Map<String, IntList>> dateHourExtractMap =broadcast.value();

注意:广播变量是只读的,不能修改它的值
spark官方建议超过2G的数据,就不适合使用广播变量,应将变量做成RDD
应用场景:
如果一个RDD中引用到外部变量,而这个变量比较大,并且任务并行度较多,应使用广播变量

3.看图看概念

这里写图片描述

这里写图片描述

2 。为什么要用广播变量?

一、一个Spark Application

Driver进程

其实就是我们写的Spark作业,打成jar运行起来的主进程。

比如一个1M的map(随机抽取的map) ,创建1000个副本,网络传输!分到1000个机器上,则占用了1G内存。

不必要的网络消耗,和内存消耗。

二、会出现的恶劣情况:

如果你是从哪个表里面读取了一些维度数据,比方说,所有商品的品类的信息,在某个算子函数中使用到100M。

1000个task 。100G的数据,要进行网络传输,集群瞬间性能下降。

三、解决方案:

如果说,task使用大变量(1M-100M),明知道会导致大量消耗。该怎么做呢?

使用广播!!

1.广播变量里面会在Driver有一份初始副本。

一个executor 会对应一份blockManager!

2.task在运行的时候,想要使用 广播变量中的数据,此时会首先在本地的Executor对应的BlockManager上 获取,如果没有。

则:
blockManager会Driver上拉取map(也有可能从距离比较近的其他节点的Executor的BlockManager上获取!这样效率更高)

四、使用广播变量的好处:

不是每个task一份副本,而是变成每个节点Executor上一个副本。
1.举例来说:

50个Executor 1000个task。
一个map10M
默认情况下,1000个task 1000个副本

1000 * 10M = 10 000M = 10 G

10G的数据,网络传输,在集群中,耗费10G的内存资源。

如果使用 广播变量,

50个Executor ,50个副本,10M*50 = 500M的数据。

网络传输,而且不一定是从Drver传输到各个节点,还可能是从就近的节点
的Executor的BlockManager上获取变量副本,网络传输速度大大增加。

之前 10000M 现在 500M。

20倍网络传输性能的消耗。20倍内存消耗的减少。
虽然说,不一定会对性能产生决定向性的作用。比如运行30分钟的spark作业,可能做了广播变量以后,速度快了2分钟。变成28分钟。

2.实际效果

没有经过任何肉条有手段的spark作业,16个小时

三板斧下来(资源,并行度,RDD重构) ,就可以到5小时。

然后重要的一个调优,影响特别大,shuffle调优,2~3小时,应用了10个以上的性能调优技术点。

JVM调优+广播后,30分钟。

整体的调优效果: 16小时 变成 30分钟!!!!

怎么使用广播变量。

原创粉丝点击