Spark性能调优之Broadcast广播大变量

Broadcast广播大变量背景:

spark作业中引用了外部变量时,spark会给每个task拷贝一份变量副本。那么,这会有什么缺点?又会对性能产生怎么用恶劣的影响呢?

Spark性能调优之Broadcast广播大变量_第1张图片
举例说明:假如有一个外部变量,大小是1M,被spark作业引用。Spark作业设置有500个task。首先,saprk会拷贝500份副本到task(如下图),而拷贝是通过网络传输的。共计就有500M全部通过网络传输,造成很大的网络开销。另外,变量副本拷贝到各个task后,占用的是内存,就有500M的内存被变量副本消耗了。内存被占用过多后,导致RDD持久化到内存时,可能无法全部写入内存,部分数据写入到磁盘,这导致了在磁盘IO上消耗性能;接着task在创建对象时,也许堆内存不够而存不下对象,这又引起频繁GC,GC时,一定会导致工作线程停止,导致spark作业暂停下来。这是一系列的恶劣影响。

解决问题:

这里引出一个角色 - BlockManager 它负责管理某个executor对应的内存和磁盘数据。

如下图:
1.Task有广播变量时,会先尝试在本地BlockManager 中找变量;
2.本地BlockManager 没找到,就会到driver去拿到变量后,把变量再拷贝保存到BlockManager ;另外,BlockManager 也有可能到距离比较近的其他节点executor的BlockManager 获取变量
3.此后这个executor的task需要广播变量时,直接使用本地BlockManager 中的变量副本。
Spark性能调优之Broadcast广播大变量_第2张图片

总结:

从给每个task拷贝,到只给BlockManager 拷贝。举例:50个executor,500个task,外部变量1M。如果不广播变量,500个task,也就是5001M=500M数据,网络传输,而且消耗500M内存资源。但使用了广播变量,只给50个executor各自对应的BlockManager拷贝数据,也就是501M=50M数据,这就减少了20倍的网络消耗,减少了20倍内存消耗。

你可能感兴趣的:(Hadoop生态,spark)