Spark一个非常重要的特性就是共享变量。 默认情况下,如果在一个算子的函数中使用到了某个外
部的变量,那么这个变量的值会被拷贝到每个task中。此时每个task只能操作自己的那份变量副
本。如果多个task想要共享某个变量,那么这种方式是做不到的。

Spark为此提供了两种共享变量,
一种是Broadcast Variable(广播变量),
另一种是Accumulator(累加变量)。

广播变量

只读 (缓存在每台worker中的cache)=》 任务与任务之间共享,不用再不同任务之间传递变量.
Broadcast Variable会将使用到的变量,仅仅为每个节点拷贝一份,更大的用处是优化性能,减少网络传输以及内存消耗。
\"在这里插入图片描述\"

  AccumulatorVariable {
  def main(args: Array[String]) {
    val conf = new SparkConf()
      .setAppName(\"AccumulatorVariable\")
      .setMaster(\"local\")
    val sc = new SparkContext(conf)

    val sum = sc.accumulator(0)

    val numberArray = Array(1, 2, 3, 4, 5)
    val numbers = sc.parallelize(numberArray, 1)
    numbers.foreach { num => sum += num }

    println(sum)
  }

累加器

只写 (通过关联操作进行\"加\"操作的变量) =》 任务与驱动器之间共享

Accumulator则可以让多个task共同操作一份变量,主要可以进行累加操作。

应用场景:调试时,对Job的执行过程中事件进行计数
例子:计算file文件中空行

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

/**
  * Created by chh on 2016/5/22.
  */
  Counter {
  def main(args :Array[String]): Unit = {
    //创建一个scala版本的SparkContext
    val conf = new SparkConf().setAppName(\"Counter\").setMaster(\"local\")
    val sc = new SparkContext(conf)
    val file=sc.textFile(\"file.txt\")
    val blankLines =sc.accumulator(0)//创建Accumulator[Int]并初始化为0
    val callSigns =file.flatMap(line => {
        if(line == \"\"){
          blankLines += 1 //累加器加一
        }
        line.split(\" \")
      })
    callSigns.saveAsTextFile(\"output.txt\")
    println(blankLines.value)
  }
}
收藏 打印