spark2.x中使用累加器

spark1.X和2.X定义累加器的方式是不同的:

累加器的作用:可以实现一个变量在不同的executor端能保持状态的累加。

使用累加器的代码实现累加:

 def main(args: Array[String]): Unit = {
    val ssc = SparkSession.builder().appName("ac").master("local[*]").getOrCreate()
    val sc = ssc.sparkContext
    val arr = Array[Int](1,2,3)
    val arrRDD = sc.parallelize(arr)
    val acc = sc.longAccumulator("accu")
    val res = arrRDD.map(t=>{
      acc.add(1L)
    })
    res.count()
    print(acc.value)

  }

这里定义了一个累加器,因为arrRDD中有3的元素,所以这里的.add方法会连续调用3次,所以这里的结果就是3

不适用累加器的代码实现累加:

  def main(args: Array[String]): Unit = {
    val ssc = SparkSession.builder().appName("ac").master("local[*]").getOrCreate()
    val sc = ssc.sparkContext
    val arr = Array[Int](1,2,3)
    val arrRDD = sc.parallelize(arr)
    var ac = 0
    val acc = sc.longAccumulator("accu")
    val res = arrRDD.map(t=>{
      ac+=1
    })
    res.count()
    println(ac)


  }

这里最后输入的值是0,为什么是0?主要是因为map算子中的计算过程是在executor端进行的,但是ac是在driver端定义的,所以driver端的ac是接收不到executor端计算过的ac的值。

 

 

使用累加器注意的事项:

防止重复累加:

  def main(args: Array[String]): Unit = {
    val ssc = SparkSession.builder().appName("ac").master("local[*]").getOrCreate()
    val sc = ssc.sparkContext
    val arr = Array[Int](1,2,3)
    val arrRDD = sc.parallelize(arr)
    var ac = 0
    val acc = sc.longAccumulator("accu")
    val res = arrRDD.map(t=>{
      acc.add(1L)
    })
    res.count()
    println(acc.value)
    res.collect()
    print(acc.value)

  }

结果为 3和6,也就是这里出现了重复累加的操作,主要是因为这里连续两次调用了action算子,所以这里累加器进行了两次重复的累加,也就是说,累加器实在遇到action算子的时候才进行累加操作的。

正确的写法:在action之前加上cache操作

  def main(args: Array[String]): Unit = {
    val ssc = SparkSession.builder().appName("ac").master("local[*]").getOrCreate()
    val sc = ssc.sparkContext
    val arr = Array[Int](1,2,3)
    val arrRDD = sc.parallelize(arr)
    var ac = 0
    val acc = sc.longAccumulator("accu")
    val res = arrRDD.map(t=>{
      acc.add(1L)
    })
    res.cache().count()
    println(acc.value)
    res.collect()
    print(acc.value)

  }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值