Spark共享变量

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

Spark为此提供了两种共享变量

  • 一种是Broadcast Variable(广播变量),
  • 另一种是Accumulator(累加变量)。

广播变量

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

object 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.
  */
object 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)
  }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章