Spark累加器
val rdd = sc.textFile...
var i=0
val rdd2 = rdd1.map(one=>{
i+=1
one
}
rdd2.collect()
println(*i=*+1)
下面代码中 输出i是多少?
package testScalaSpark
import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession
object AccumulatorTest {
def main(args: Array[String]): Unit = {
val spark: SparkSession = SparkSession.builder().appName("test").master("local").getOrCreate()
val sc= spark.sparkContext
val rdd = sc.textFile("./data/words")
var i =0
var rdd2 = rdd.map(one=>{
i+=1
//println(s"execultor $i")
one
})
rdd2.collect()
println(s"$i")
}
}
结果是0
如果我们把map中的 取消注释println(s"execultor $i")
会发现在map中,i是累加的,但是最后打印的i 还是0
如图
在Driver上·定义i=0,然后发送到task到executor中,在 executor中i累加。因为最后的println是在Driver上的,所以打印的i还是0
所以需要将上图中的 Executor中的i累加的值在返回Driver中,然后再求和,
累加器是分布式里统筹的概念,而不是全局变量的概念,因为是分布式的,多个节点之间不能称为全局
注意:累加器在Driver定义初始化,在1.6版本中Executor中不能获取累加器的值
package testScalaSpark
import org.apache.spark.SparkConf
import org.apache.spark.sql.SparkSession
import org.apache.spark.util.LongAccumulator
object AccumulatorTest {
def main(args: Array[String]): Unit = {
val spark: SparkSession = SparkSession.builder().appName("test").master("local").getOrCreate()
val sc= spark.sparkContext
val acc: LongAccumulator = sc.longAccumulator
val rdd = sc.textFile("./data/words")
var i =0
var rdd2 = rdd.map(one=>{
acc.add(1)
println(s"Executor acc = ${acc.value} ")
//println(s"execultor $i")
one
})
rdd2.collect()
// println(s"$i")
println(s"acc = ${acc.value}")
}
}
使用后还是可以在driver中打印出最新值的,而不是0