Spark aprende de 0 a 1 (4) -Apache Spark broadcast variables y acumuladores

1. Variables de transmisión

1.1 Diagrama de comprensión de la variable de transmisión

Inserte la descripción de la imagen aquí

1.2 Uso de variables de difusión

object SparkBroadCast {
    
    
  def main(args: Array[String]): Unit = {
    
    
    val conf = new SparkConf();
    conf.setMaster("local")
    conf.setAppName("SparkBroadCast")
    val sparkContext = new SparkContext(conf)
    val list = List("spark","hadoop","flink")
    //广播 list
    val brodcast = sparkContext.broadcast(list)
    val wordList = List("spark","hadoop","java","python")
    sparkContext.parallelize(wordList).filter(word => {
    
    
      // 使用广播变量
      val value = brodcast.value
      value.contains(word)
    }).foreach(println)
  }
}

1.3 Asuntos que necesitan atención

  • ¿Se puede transmitir un RDD utilizando variables de transmisión?

    No, porque RDD no almacena datos. Puede difundir los resultados del RDD.

  • Las variables de difusión solo se pueden definir en el lado del conductor, no en el lado del ejecutor.

  • El valor de la variable de difusión se puede modificar en el lado del controlador y el valor de la variable de difusión no se puede modificar en el lado del ejecutor.

2. Acumulador

2.1 El diagrama de comprensión del acumulador

Inserte la descripción de la imagen aquí

2.2 El uso de acumulador

object SparkAccumulator {
    
    

  def main(args: Array[String]): Unit = {
    
    
    val conf = new SparkConf();
    conf.setAppName("SparkAccumulator")
    conf.setMaster("local")
    val sparkContext = new SparkContext(conf)
    // 定义一个累加器
    val acc = sparkContext.longAccumulator;
    val list = List("kafka","java","spark","hadoop","flink")
    // 循环rdd,统计有多少个word
    sparkContext.parallelize(list).foreach(word => acc.add(1))
    val value = acc.value
    println(value)
    sparkContext.stop()
  }
}

2.3 Acumulador personalizado

  1. Heredar AccumulatorV2, definir el tipo de entrada y salida como INT

    package com.abcft.spark.acc
    import org.apache.spark.util.AccumulatorV2
    
    class CustomAcc extends AccumulatorV2[Int ,Int] {
          
          
    
      var acc= 0
      override def isZero: Boolean = acc == 0
    
      override def copy(): AccumulatorV2[Int, Int] = {
          
          
        var v = new CustomAcc()
        v.acc = this.acc
        return v;
      }
    
      override def reset(): Unit = {
          
          
        var v = new CustomAcc()
      }
    
      override def add(v: Int): Unit = {
          
          
        this.acc = this.acc + v
      }
    
      override def merge(other: AccumulatorV2[Int, Int]): Unit = {
          
          
        this.acc = other.value + this.acc
      }
    
      override def value: Int = this.acc
    }
    
  2. Usa un acumulador personalizado

    import com.abcft.spark.acc.CustomAcc
    import org.apache.spark.{
          
          SparkConf, SparkContext}
    
    object SparkCustomAcc {
          
          
    
      def main(args: Array[String]): Unit = {
          
          
        val conf = new SparkConf();
        conf.setMaster("local")
        conf.setAppName("SparkCustomAcc")
        val sparkContext = new SparkContext(conf);
        // 创建累加器
        val acc = new CustomAcc()
        sparkContext.register(acc,"CustomAcc")
        val list = List("kafka","java","spark","hadoop","flink")
        // 循环rdd,统计有多少个word
        sparkContext.parallelize(list).foreach(word => acc.add(1))
        val value = acc.value
        println(value)
        sparkContext.stop()
      }
    }
    

2.4 Problemas principales

El acumulador se define en el lado del Conductor y se le asigna un valor inicial, el acumulador solo se puede leer en el lado del Conductor y actualizar en el lado del Ejecutor.

Supongo que te gusta

Origin blog.csdn.net/dwjf321/article/details/109048090
Recomendado
Clasificación