Directorio de artículos
1. Variables de transmisión
1.1 Diagrama de comprensión de la variable de transmisión
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
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
-
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 }
-
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.