spark闭包原理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/mn_kw/article/details/81974830

spark中非常难以理解的概念,就是在集群分布式并行运行时操作算子外部的变量生命周期

所谓RDD算子中,操作作用域外部的变量,指的是,类似下面的语句:val a = 0 ; rdd.foreach(i -> a +=1)

此时,对rdd执行foreach算子的作用阈,其实仅仅是它内部代码,但是这里却操作了作用阈外部的变量a,这种现象就是闭包

闭包简单来说,就是i操作一个不属于一个作用域范围的变量

如果使用local模式运行spark作业,那么实际只有一个jvm进程在执行这个作业

此时,你所有的RDD算子的代码执行以及它们操作的外部变量,都是在一个进程内存中,这个进程就是driver进程,此时是没有任何问题的

但是在作业提交到集群执行前,spark会在driver端处理闭包

spark中的闭包,特指哪些,不在算子的作用域nebula,但是在作用阈外部却被算子处理和操作的这些变量

而算子代码的执行也需要这些变量才能顺利执行

此时,这些闭包变量会被序列化成多个副本,然后每个副本都发送到各个executor进程中,供那个executor进程运行的task执行代码时使用

闭包变量发送到executor进程中之后,就变成了一个一个独立的变量副本了,这就是最关键的一点

此时在executor进程中,也有一个变量副本,但是缺完全跟各个executor进程照顾你的变量副本不是一个东西

此时,各个executor进程对于自己内存中的变量副本进行操作,即使改变了变量副本的值,但是对于driver端的程序,是完全感知不到的,driver端的变量没有被进行任何操作

因此,在使用集群模式运行作业的时候,切记不要在算子内部,对作用域外部的闭包变量进行改变值操作,因为那没有任何意义,算子仅仅在executor进程中改变副本的值

这里我们需要用到我们的Accumulator累加变量来对外部变量做操作

猜你喜欢

转载自blog.csdn.net/mn_kw/article/details/81974830