Desarrollo de big data: comprensión de los cierres con Spark

1. Comprensión de los cierres de Scala

Un cierre es una función cuyo valor de retorno depende de una o más variables declaradas fuera de la función. Los cierres generalmente se pueden considerar simplemente como otra función que puede acceder a variables locales en una función.

Como la siguiente función anónima:

val multiplier = (i:Int) => i * 10  

Hay una variable i en el cuerpo de la función, que sirve como parámetro de la función. Como otro fragmento de código a continuación:

val multiplier = (i:Int) => i * factor

En multiplierHay dos variables: i y factor. Donde i es una forma de una función de los parámetros, la multiplierfunción se llama, se me ha dado un nuevo valor. Sin embargo, el factor no es un parámetro formal, sino una variable libre. Considere el siguiente código:

var factor = 3  val multiplier = (i:Int) => i * factor 

Aquí introducimos una variable libre factor, que se define fuera de la función.

Variables de función así definidas multipliercomo un "cierre", ya que se refiere a la variable fuera de la definición de función, la definición de esta función de proceso es capturar la variable libre para formar una función cerrada

Ejemplo completo:

object Test {  
   def main(args: Array[String]) {  
      println( "muliplier(1) value = " +  multiplier(1) )  
      println( "muliplier(2) value = " +  multiplier(2) )  
   }  
   var factor = 3  
   val multiplier = (i:Int) => i * factor  
}

2. Comprensión de los cierres en Spark

Primero mire el siguiente fragmento de código:

val data=Array(1, 2, 3, 4, 5)
var counter = 0
var rdd = sc.parallelize(data)

// ???? 这样做会怎么样
rdd.foreach(x => counter += x)

println("Counter value: " + counter)

Lo primero que hay que asegurarse es que el resultado de la salida anterior es 0, y park descompone el procesamiento de las operaciones RDD en tareas, y cada tarea se Executorejecuta. Antes de la ejecución, Spark calcula el cierre de la tarea. Los cierres son Executoraquellas variables y métodos que deben estar visibles al realizar cálculos en el RDD (foreach () en este caso). El cierre se serializará y se enviará a cada Ejecutor, pero la copia se enviará al Ejecutor, por lo que la salida en el Controlador sigue siendo counterella misma, si desea actualizar el global, use el acumulador y spark-streamingutilícelo updateStateByKeypara actualizar el estado público.

Además, los cierres en Spark tienen otras funciones.

1. Borre las variables globales inútiles enviadas por el controlador al ejecutor y solo copie la información de la variable útil al ejecutor

2. Asegúrese de que los datos enviados al Ejecutor sean datos serializados

Por ejemplo, al usar DataSet, la definición de la clase de caso debe estar debajo de la clase, no dentro del método. Incluso si no hay ningún problema con la sintaxis, si ha usado json4s para serializar, implicit val formats = DefaultFormatsla importación debe colocarse debajo de la class, de lo contrario, la secuencia de formato debe ser separada incluso si no la usa para nada más.

3. Resumen

Los cierres son visibles en todas partes en todo el ciclo de vida de Spark, por ejemplo Driver, todos los datos copiados desde arriba deben ser serializados + cierres Executor.

Wu Xie, Xiao San Ye, un pequeño novato en segundo plano, big data e inteligencia artificial. Presta atención a másarchivo

Supongo que te gusta

Origin blog.csdn.net/hu_lichao/article/details/112451982
Recomendado
Clasificación