es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Log4j2 muestra registros en un bucle “foreach” dentro del registro del ejecutor, pero no en el método “map” en el registro del ejecutor.

Estoy usando Spark 2.3.0.

Cuando uso foreach dentro de un dataframe y registro mensajes, puedo ver los registros en el registro del ejecutor. Pero, ¿por qué no imprime los registros en el método map?

val df = Seq((0)).toDF("a")

df.foreachPartition { iterator =>
  {
    iterator.map { row =>
      {
        val LOGGER = LogManager.getLogger(getClass.getName)
        Configurator.setRootLevel(Level.INFO);
        LOGGER.info("Probando el registro en el ejecutor")
      }
    }
  }
} //No imprime en el registro del ejecutor

df.foreachPartition { iterator =>
  {
    iterator.foreach { row =>
      {
        val LOGGER = LogManager.getLogger(getClass.getName)
        Configurator.setRootLevel(Level.INFO);
        LOGGER.info("Probando el registro en el ejecutor")
      }
    }
  }
} //Imprime registros del ejecutor

¿Cuál es la razón de esto y hay alguna manera de lograrlo (estoy usando Log4j2 con el archivo log42.properties)?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    La razón por la que los registros no se imprimen en el método map es que map es una operación de transformación y se ejecuta de forma perezosa. Cuando se llama a map, devuelve un nuevo dataframe sin activar ninguna acción. Por lo tanto, el código dentro del método map no se ejecuta realmente hasta que se llama a una acción en el dataframe.

    En cambio, el método foreach es una acción y se ejecuta de inmediato. Por lo tanto, los registros dentro del método foreach se pueden imprimir en el registro del ejecutor.

    Para lograr el registro en el método map, puedes usar el método foreach en lugar de map para activar la acción. Alternativamente, puedes convertir el dataframe en un RDD y luego utilizar la transformación map en el RDD, seguida de la acción foreach. Esto asegurará que el código dentro del método map se ejecute y los registros se impriman en el registro del ejecutor.

    Por ejemplo:

    import org.apache.spark.sql.Row
    
    val df = Seq((0)).toDF("a")
    
    val rdd = df.rdd.map { row: Row =>
      val LOGGER = LogManager.getLogger(getClass.getName)
      Configurator.setRootLevel(Level.INFO);
      LOGGER.info("Prueba del registro en el ejecutor")
      row
    }
    
    rdd.foreach { row: Row =>
      // Hacer algo con la fila
    }
    

    Ten en cuenta que si decides utilizar foreach dentro de la transformación map, no garantiza que los registros se impriman en orden, ya que foreach se ejecuta en paralelo en múltiples particiones.

Comments are closed.