Spark中的广播变量和累加器

481 阅读2分钟

广播变量(Broadcast Variables)

  • 为什么要使用广播变量?

    如果我们在分布式计算里面分发大对象,例如:字典、集合、黑白名单,这个都会由Driver端进行分发,一般来讲,如果这个变量不是广播变量,那么每个task就会分发一份,这在task数目十分多的情况下,Driver的宽带就会成为系统的瓶颈,而且会大量消耗task服务器上的资源,如果将这个变量设置为广播变量,那么只使每个executor拥有一份,这个executor启动的task会共享这个变量,从而节省了通信的成本和服务器的资源。

  • 举例

    假设:有一个大小为100M的集合,在driver端生成,但是在所有的task中需要使用。那么每一个task都会维持一个当前这100M的数据,如果一个executor中启动了6个task,最终会消耗600M内存。

    如果使用广播变量:只会在executor消耗100M内存

  • 效果

    • 1、减少了网络传输数据的量
    • 2、减少了executor的内存使用量
  • 注意事项

    • 1、能不能将一个RDD使用广播变量广播出去?答:不能,因为RDD不是存储数据的,可以将RDD的结果广播出去
      
    • 2、广播变量只能在Driver端定义,不能在Executor端定义
    • 3、在Driver端可以修改广播变量的值,在Executor端无法修改广播变量的值
    • 4、如果Executor端用到了Driver端的变量,如果不使用广播变量在Executor有多少个task就有多少个Driver端的变量副本 - 5、如果Executor端用到了Driver端的变量,如果使用广播变量在每个Executor中都只有一份Driver端的变量副本

累加器(Accumulators)

  • 为什么要定义累加器?

    在Spark应用程序中,我们经常会有这样的需求,如异常监控、调式、记录符合某特性的数据的节目。这种需求都需要用到计数器,如果一个变量不被生命为累加器,那么它将在被改变时不会在Driver端进行全局汇总,即在分布式运行时,每个task运行的都只是原始变量的一个副本,并不能改变原始变量的值,但是当这个变量被声明为累加器后,该变量就会有分布式计算的功能。

  • 注意

    Spark的累加器和MapReduce中的全局计数器是一个道理,其实是一样的事务,工作原理也一样。