Acumulador personalizado de chispas (1)

Acumulador personalizado (tipo de suma)

Escenario de aplicación : el lado del conductor define una variable compartida y acumula los datos en la variable. Si utiliza directamente operadores iterativos como foreach o map, la variable acumulada no se puede devolver al lado del conductor, porque el proceso de acumulación tiene lugar en el lado del Ejecutor. Generalmente se usa en escenarios de conteo, las variables a menudo se declaran en el lado del Conductor.

Características : Las variables están en el lado del Conductor y el proceso de acumulación está en el lado del Ejecutor. En el proceso de acumulación, el lado del Ejecutor no puede leer su valor. Si desea leer su valor,
solo puede leerlo en el lado del Conductor.
Uso :
1. Crear una instancia del acumulador
2. Registrar un acumulador a través de sc.register ()
3. Agregar datos a
través del nombre real del acumulador . Agregar 4. Pasar el nombre de la instancia del acumulador. Valor hacia y desde el valor del acumulador

import org.apache.spark.{
    
    SparkConf, SparkContext}
import org.apache.spark.util.{
    
    AccumulatorV2, DoubleAccumulator, LongAccumulator}

object AccumulatorV2Demo_2 {
    
    
  def main(args: Array[String]): Unit = {
    
    
    val conf = new SparkConf().setAppName(this.getClass.getName).setMaster("local[2]")
    val sc = new SparkContext(conf)
    val nums1 = sc.parallelize(List(1,2,3,4,5,6,7,8,9),2)
    val nums2 = sc.parallelize(List(1.2,2.4,3.4,4.0,5.0,6.0,7.0,8.0,9.0),2)
    //获取自定义accumulator累加器的实例
    val accumulator = new MyAccumulator()
    //注册
    sc.register(accumulator,"acc")
    nums1.foreach(x=> accumulator.add(x))
    println(accumulator.value)
    sc.stop()
  }
}

/**
 * AccumulatorV2[in,out]:需要自定义输入类型和输出类型
 */
class MyAccumulator extends  AccumulatorV2[Int,Int]{
    
    
  //初始化一个输出值变量
  private  var sum :Int =_

  /**
   * 检查方法是否为空
   * @return
   */
  override def isZero: Boolean = sum==0

  /**
   * copy一个新的累加器
   * @return
   */
  override def copy(): AccumulatorV2[Int, Int] = {
    
    
    val acc = new MyAccumulator
    acc.sum = this.sum
    acc
  }

  /**
   * 重置一个累加器,相当于将累加器的数据清零
   */
  override def reset(): Unit = sum=0

  /**
   * 局部聚合:每一个分区中进行累加的过程
   * @param v
   */
  override def add(v: Int): Unit = {
    
    
    sum += v
  }

  /**
   * 全局聚合,将各个分区的结果进行合并的过程
   * @param other
   */
  override def merge(other: AccumulatorV2[Int, Int]): Unit = {
    
    
    sum +=other.value
  }

  /**
   * 最终的结果,可以对该方法中结果数据,进行操作再返回
   * @return
   */
  override def value: Int = sum
}

Supongo que te gusta

Origin blog.csdn.net/qq_42706464/article/details/108440525
Recomendado
Clasificación