spark的广播变量和累加器的用法

版权声明:原创文章,转载请注明出处 https://blog.csdn.net/xianpanjia4616/article/details/82721977

今天我们主要来说一下spark的广播变量和累加器的具体使用,先来看一下官网的介绍:

共享变量

通常,当在远程集群节点上执行传递给Spark操作(例如map,reduce)的函数时,它将在函数中使用的所有变量的单独副本上工作.这些变量将复制到每台计算机,并且远程计算机上的变量更新不会传播回驱动程序.支持跨任务的通用,读写共享变量效率低下.但是,Spark确实为两种常见的使用模式提供了两种有限类型的共享变量:广播变量和累加器.

广播变量

广播变量允许程序员在每台机器上保留一个只读变量,而不是随副本一起发送它的副本.例如,它们可用于以有效的方式为每个节点提供大输入数据集的副本.Spark还尝试使用有效的广播算法来分发广播变量,以降低通信成本.

Spark动作通过一组阶段执行,由分布式“shuffle”操作分隔.Spark自动广播每个阶段中任务所需的公共数据.以这种方式广播的数据以序列化形式缓存并在运行每个任务之前反序列化.这意味着显式创建广播变量仅在跨多个阶段的任务需要相同数据或以反序列化形式缓存数据很重要时才有用.

广播变量是v通过调用从变量创建的SparkContext.broadcast(v).广播变量是一个包装器v,可以通过调用该value方法来访问它的值.

累加器

累加器是仅通过关联和交换操作“添加”的变量,因此可以并行地有效支持。它们可用于实现计数器(如MapReduce)或总和。Spark本身支持数值类型的累加器,程序员可以添加对新类型的支持。

作为用户,您可以创建命名或未命名的累加器。如下图所示,命名累加器(在此实例中counter)将在Web UI中显示修改该累加器的阶段。Spark显示“任务”表中任务修改的每个累加器的值。

下面我们看一下demo,我把广播变量和累计器写在一块了,用于算出广播变量中的词出现了多少次,直接看代码吧:

package test

import org.apache.spark.{SparkConf, SparkContext}

/**
  * spark的累加器;
  */
object accumulator {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setAppName("localTest").setMaster("local[2]")
    val sc = new SparkContext(conf)
    val acc = sc.longAccumulator("accumulator_")
    val broadcastList = sc.broadcast(List("hello"))
    val rdd = sc.textFile("D:/test.txt",5)
    val word = rdd.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)
    word.foreachPartition(x=>{
      x.foreach(y=>{
        println(y._1 + "-----" + y._2)
        if(broadcastList.value.contains(y._1)){
          acc.add(y._2)
        }
      })
    })
    println("包含hello的有多少个:" + acc.value)
  }
}

执行的结果如下:

jim-----1
girl-----1
hello-----3
morning-----1
jason-----1
today-----1
包含hello的有多少个:3

注意事项:

1,广播变量是一个只读变量,在driver端定义后,在excetors端只能读它的值,不能修改.

2,累加器在Driver端定义赋初始值,累加器只能在Driver端读取最后的值,在Excutor端更新.在driver端获取累计器值的时候需要一个action操作来触发,才能拿到值,并且累计器只能增加,不能减少.

如果有写的不对的地方,欢迎大家指正,如果有什么疑问,可以加QQ群:340297350,谢谢

 

猜你喜欢

转载自blog.csdn.net/xianpanjia4616/article/details/82721977