eclipse - Depuración de aplicaciones Spark
debugging apache-spark (5)
¿Ha intentado pasar parámetros de depuración remotos a JVM de trabajo? Creo que es algo así como spark.executor.extraJavaOptions. Entonces debería poder conectarse a la JVM del trabajador remoto desde Eclipse.
A ver si esto ayuda. https://abrv8.wordpress.com/2014/10/06/debugging-java-spark-applications/
Estoy intentando depurar una aplicación Spark en un clúster utilizando un maestro y varios nodos de trabajo. He tenido éxito en la configuración del nodo maestro y los nodos de trabajo con Spark standalone cluster manager. Descargué la carpeta de chispas con archivos binarios y uso los siguientes comandos para configurar nodos trabajadores y maestros. Estos comandos se ejecutan desde el directorio de la chispa.
comando para lanzar maestro
./sbin/start-master.sh
comando para lanzar nodo trabajador
./bin/spark-class org.apache.spark.deploy.worker.Worker master-URL
comando para enviar la solicitud
./sbin/spark-submit --class Application --master URL ~/app.jar
Ahora, me gustaría entender el flujo de control a través del código fuente de Spark en los nodos de trabajo cuando presento mi solicitud (solo quiero usar uno de los ejemplos dados que usan reduce ()). Supongo que debería configurar Spark en Eclipse. El link configuración de Eclipse en el sitio web de Apache Spark parece estar roto. Agradecería alguna orientación sobre la configuración de Spark y Eclipse para permitir el paso a través del código fuente de Spark en los nodos de trabajo.
¡Gracias!
Cuando ejecuta una aplicación de chispa en el hilo, hay una opción como esta:
YARN_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5455 $YARN_OPTS"
Puede agregarlo a yarn-env.sh
y la depuración remota estará disponible a través del port 5455
.
Si usa chispa en modo independiente, creo que esto puede ayudar:
export SPARK_JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
Es importante distinguir entre depurar el programa del controlador y depurar uno de los ejecutores. Se requieren diferentes opciones para spark-submit
a la spark-submit
Para depurar el controlador, puede agregar lo siguiente a su comando spark-submit
. Luego, configure su depurador remoto para que se conecte al nodo en el que inició el programa del controlador.
--driver-java-options -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005
En este ejemplo, se especificó el puerto 5005, pero es posible que deba personalizarlo si algo ya se está ejecutando en ese puerto.
La conexión a un ejecutor es similar, agregue las siguientes opciones a su comando de spark-submit
.
--num-executors 1 --executor-cores 1 --conf "spark.executor.extraJavaOptions=-agentlib:jdwp=transport=dt_socket,server=n,address=wm1b0-8ab.yourcomputer.org:5005,suspend=n"
Reemplace la dirección con la dirección de su computadora local. (Es una buena idea probar que puede acceder a él desde su grupo de chispas).
En este caso, inicie su depurador en modo de audición, luego inicie su programa spark y espere a que el ejecutor se conecte a su depurador. Es importante establecer el número de ejecutores en 1 o varios ejecutores intentarán conectarse a su depurador, lo que probablemente cause problemas.
Estos ejemplos son para ejecutar con el conjunto sparkMaster
como yarn-client
aunque también pueden funcionar cuando se ejecutan bajo mesos. Si está ejecutando el modo de yarn-cluster
, es posible que tenga que configurar el controlador para que se conecte a su depurador en lugar de adjuntar su depurador al controlador, ya que no necesariamente sabrá de antemano en qué nodo se ejecutará el controlador.
Había seguido los mismos pasos para configurar un clúster independiente de chispa. Pude depurar el controlador, master, trabajo y ejecutor de JVM.
El maestro y el nodo de trabajo se configuran en una máquina de clase de servidor. La máquina tiene 12 núcleos de CPU. El código fuente de Spark -2.2.0 ha sido clonado desde el Spark Git Repo.
PASOS:
1] Comando para iniciar la JVM Master:
root@ubuntu:~/spark-2.2.0-bin-hadoop2.7/bin#
./spark-class -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8787 org.apache.spark.deploy.master.Master
El shell script spark-class se utiliza para iniciar el maestro manualmente. Los primeros argumentos son argumentos de JVM que inician el maestro en modo de depuración. La JVM se suspende y espera a que el IDE realice una conexión remota.
A continuación se muestran las capturas de pantalla que muestran la configuración IDE para la depuración remota:
2] Comando para lanzar la JVM Worker:
root@ubuntu:~/spark-2.2.0-bin-hadoop2.7/bin# ./spark-class -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8788 org.apache.spark.deploy.worker.Worker spark://10.71.220.34:7077
Igual que el maestro, el último argumento especifica la dirección del maestro de chispas. El puerto de depuración para el trabajador es 8788.
Como parte del lanzamiento el trabajador se registra con el maestro.
Captura de pantalla
3] Una aplicación Java básica con un método principal se compila y se envuelve en un frasco uber / fat. Esto ha sido explicado en el texto "chispa de aprendizaje". Básicamente, un frasco de Uber contiene todas las dependencias transitivas.
Creado ejecutando el paquete mvn en el siguiente directorio:
root@ubuntu:/home/customer/Documents/Texts/Spark/learning-spark-master# mvn package
Lo anterior genera un jar en la carpeta ./target.
La siguiente captura de pantalla es la aplicación java, que se enviaría al Spark Cluster:
4] Comando para enviar el comando al clúster independiente
root@ubuntu:/home/customer/Documents/Texts/Spark/learning-spark-master# /home/customer/spark-2.2.0-bin-hadoop2.7/bin/spark-submit --master spark://10.71.220.34:7077
--conf "spark.executor.extraJavaOptions=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8790"
--conf "spark.executor.extraClassPath=/home/customer/Documents/Texts/Spark/
learning-spark-master/target/java-0.0.2.jar"
--class com.oreilly.learningsparkexamples.java.BasicMapToDouble
--name "MapToDouble"
./target/java-0.0.2.jar
spark://10.71.220.34:7077 → Argument to the java program →
com.oreilly.learningsparkexamples.java.BasicMapToDouble
· El comando anterior proviene del nodo cliente que ejecuta la aplicación con el método principal. Sin embargo, las transformaciones se ejecutan en el ejecutor remoto JVM.
·
Los parámetros –conf son importantes. Se utilizan para configurar las JVM''s del ejecutor. Los JVMS de Ejecutor se inician en tiempo de ejecución por los JVM de Trabajadores.
· El primer parámetro conf especifica que la JVM Executor debe iniciarse en modo de depuración y suspenderse de inmediato. Aparece en el puerto 8790.
· El segundo parámetro conf especifica que la ruta de la clase del ejecutor debe contener los archivos específicos de la aplicación que se envían al ejecutor. En una configuración distribuida, estos tarros se deben mover a la máquina JVM Executor.
· El último argumento es usado por la aplicación cliente para conectarse al maestro de chispas.
Para comprender cómo la aplicación cliente se conecta al clúster Spark, debemos depurar la aplicación cliente y pasar a través de ella. Para eso necesitamos configurarlo para que se ejecute en el modo de depuración.
Para depurar el cliente , necesitamos editar el script spark-submit de la siguiente manera:
Contenidos de la chispa de envío.
exec "${SPARK_HOME}"/bin/spark-class -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8789 org.apache.spark.deploy.SparkSubmit "$@"
5] Después de que el cliente se registra, el trabajador inicia un ejecutor en tiempo de ejecución en un subproceso diferente.
La captura de pantalla de abajo muestra la clase ExecutorRunner.scala
6] Ahora nos conectamos a la JVM ejecutora bifurcada utilizando el IDE. El ejecutor JVM ejecutaría las funciones de transformación en nuestra aplicación enviada.
JavaDoubleRDD result = rdd.mapToDouble( → ***Transformation function/lambda***
new DoubleFunction<Integer>() {
public double call(Integer x) {
double y = (double) x;
return y * y;
}
});
7] La función de transformación se ejecuta, solo cuando se invoca la acción "recopilar" .
8] La captura de pantalla siguiente muestra la vista Ejecutor, cuando la función mapToDouble se invoca en paralelo en varios elementos de la lista. El ejecutor JVM ejecuta la función en 12 subprocesos, ya que hay 12 núcleos. Como el número de núcleos no se estableció en la línea de comando, la JVM de trabajo configuró la opción por defecto: -cores = 12.
9] Captura de pantalla que muestra el código enviado por el cliente [maptodouble ()] que se ejecuta en la JVM ejecutora remota bifurcada.
10] Después de que se hayan ejecutado todas las tareas, el Executor JVM sale. Una vez que se cierra la aplicación cliente, el nodo de trabajo se desbloquea y espera el próximo envío.
Referencias
https://spark.apache.org/docs/latest/configuration.html
He creado un blog que describe los pasos sobre cómo depurar estos subsistemas. Con suerte, esto ayuda a otros.
Blog que describe los pasos:
https://sandeepmspark.blogspot.com/2018/01/spark-standalone-cluster-internals.html
Podría ejecutar la aplicación Spark en modo local si solo necesita depurar la lógica de sus transformaciones. Esto se puede ejecutar en su IDE y podrá depurar como cualquier otra aplicación:
val conf = new SparkConf().setMaster("local").setAppName("myApp")
Por supuesto, no está distribuyendo el problema con esta configuración. Distribuir el problema es tan fácil como cambiar el maestro para que apunte a su grupo.