spark调优----广播变量

广播变量
       在Spark Application中,经常会使用到一个共享变量,众所周知的,Spark是一个并行计算框架,对于这个变量,每一个executor的task在访问它的时候,都会去拷贝一份副本去使用。如下图所示:

图一


       1.对于这种默认方式,它会极大的系统的内存,我们可以假设一个集群中有1024个task,这个共享变量大小假设为1M,那么就会去复制1024份到集群上去,这样就会有1个G的数据在网络中传输,并且系统需要耗费1G内存去为这些副本分配空间,这样对于系统有什么影响呢?
       2.如果系统内存不足,RDD持久化的时候无法在内存中持久化,需要持久化到磁盘中,那么后续的操作会因为频繁的磁盘IO使得速度变慢,性能下降,当task中创建对象时,发现堆中内存不足,那么就需要进行GC操作,进行GC的时候,会导致工作线程暂停,如果内存严重不足,频繁的GC对于Spark作业的速度的影响是可想而知的
解决方法:
       针对这个情况我们可以使用Broadcast,将这种每个task需要用到的共享变量广播出去。
       从上面的图中可以看到,当每一个task需要使用这个变量的时候都会拷贝一份。如果使用广播变量,首先该广播变量会拷贝一份副本到Driver中,当每一个executor的task使用到该变量时,首先会去每个executor的BlockManager中去检查是否有该变量的副本,如果没有,接着会去Driver中去拷贝一份副本到BlockManager中,然后供该executor中的每一个task使用,到下一个executor的task需要使用这个变量时,它的BlockManager可以去Driver中拷贝副本,也可以去距离比较近的executor的BlockManager中去拷贝。(每一个executor中的BlockManager的作用是负责管理每一个executor对应的内存和磁盘的数据。)其原理图如上所示
   

图二


       在默认情况下,如果是1024个task需要消耗1G内存,但是如果我们有50个executor来平分这些task,那么只需要50个副本即可,总共消耗了50M内存,那么在内存的消耗了节省了大约20倍。而且副本的复制有时不需要从Driver拷贝,而是从其他executor中拷贝,那么,网络 传输带来的性能消耗也会小很多,可想而知,使用广播变量可以节省很多内存,从而使得性能显著提升
广播方法
      比如我们的共享变量是一个map类型的变量,我们可以使用Spark上下文来创建广播变量:
      Broadcast<Map<String>> broadcast=sc.broadcast(map);1
      在task中使用的时候可以使用value方法或者getValue方法来获取它的值:
      Map<String> map=broadcast.value;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值