理解spark中的闭包问题

                                                                               理解spark中的闭包

(spark官方文档“spark.apachecn.org”解释)

理解spark中的闭包问题

什么叫闭包: 跨作用域(即在work节点访问driver节点访问函数变量。又指的一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

理解spark中的闭包问题

代码展示:

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

  val rdd = sc.parallelize(List(1,2,3))
  var counter = 0
  //warn: don't do this
  rdd.foreach(x => counter += x)
  println("Counter value: "+counter)

  sc.stop()
}

 

问题分析: 

counter是在foreach函数外部定义的,也就是说是在driver程序中定义,而foreach函数是属于RDD的,RDD函数的执行位置为各个worker节点上(或者是在worker进程),main函数是在driver节点上(或者说driver进程上)执行的,所以当counter变量在driver中定义,被RDD函数使用的时候就出现了跨域的问题,也就是闭包问题

问题解释: 

由于main函数和RDD对象的foreach函数是属于不同闭包的,所以,传进foreach函数的counter是一个副本,初始值都为0。foreach中叠加的是counter的副本,不管副本如何变化,都不会影响到main函数中的counter,所以最终结果还是0。