Supongamos por lo siguiente que solo se está ejecutando un trabajo de Spark en cada momento.
Lo que llego hasta ahora
Esto es lo que entiendo que sucede en Spark:
- Cuando
SparkContext
se crea un, cada nodo de trabajo inicia un ejecutor. Los ejecutores son procesos separados (JVM), que se conectan nuevamente al programa del controlador. Cada ejecutor tiene el frasco del programa controlador. Renunciar a un conductor, apaga a los ejecutores. Cada ejecutor puede contener algunas particiones. - Cuando se ejecuta un trabajo, se crea un plan de ejecución de acuerdo con el gráfico de linaje.
- El trabajo de ejecución se divide en etapas, donde las etapas contienen tantas transformaciones y acciones vecinas (en el gráfico de linaje), pero no barajan. Por lo tanto, las etapas están separadas por barajaduras.
Entiendo que
- Una tarea es un comando enviado desde el controlador a un ejecutor al serializar el objeto Function.
- El ejecutor deserializa (con el controlador jar) el comando (tarea) y lo ejecuta en una partición.
pero
Pregunta (s)
¿Cómo divido el escenario en esas tareas?
Específicamente:
- ¿Las tareas están determinadas por las transformaciones y acciones o pueden ser múltiples transformaciones / acciones en una tarea?
- Son las tareas determinadas por la partición (por ejemplo, una tarea por etapa por partición).
- ¿Las tareas están determinadas por los nodos (por ejemplo, una tarea por etapa por nodo)?
Lo que pienso (solo respuesta parcial, incluso si es correcto)
En https://0x0fff.com/spark-architecture-shuffle , el shuffle se explica con la imagen
y tengo la impresión de que la regla es
cada etapa se divide en # tareas de número de particiones, sin tener en cuenta el número de nodos
Para mi primera imagen, diría que tendría 3 tareas de mapa y 3 tareas de reducción.
Para la imagen de 0x0fff, diría que hay 8 tareas de mapa y 3 tareas de reducción (suponiendo que solo haya tres archivos naranja y tres verde oscuro).
Preguntas abiertas en cualquier caso
¿Es eso correcto? Pero incluso si eso es correcto, mis preguntas anteriores no están todas respondidas, porque todavía está abierto, ya sea que varias operaciones (por ejemplo, múltiples mapas) estén dentro de una tarea o estén separadas en una tarea por operación.
Lo que otros dicen
¿Qué es una tarea en Spark? ¿Cómo ejecuta el trabajador Spark el archivo jar? y ¿Cómo divide el planificador Apache Spark los archivos en tareas? son similares, pero no sentí que mi pregunta fuera respondida claramente allí.
fuente
sum(..)
que tomara en cuenta esa variación.Esto podría ayudarlo a comprender mejor las diferentes piezas:
fuente
Si entiendo correctamente, hay 2 cosas (relacionadas) que te confunden:
1) ¿Qué determina el contenido de una tarea?
2) ¿Qué determina el número de tareas a ejecutar?
El motor de Spark "pega" operaciones simples en rdds consecutivos, por ejemplo:
así que cuando se calcula (perezosamente) rdd3, spark generará una tarea por partición de rdd1 y cada tarea ejecutará tanto el filtro como el mapa por línea para dar como resultado rdd3.
El número de tareas está determinado por el número de particiones. Cada RDD tiene un número definido de particiones. Para un RDD de origen que se lee desde HDFS (usando sc.textFile (...) por ejemplo), el número de particiones es el número de divisiones generadas por el formato de entrada. Algunas operaciones en RDD (s) pueden resultar en un RDD con un número diferente de particiones:
Otro ejemplo es une:
(La mayoría) de las operaciones que cambian el número de particiones implican una combinación aleatoria, cuando hacemos, por ejemplo:
lo que realmente sucede es que la tarea en cada partición de rdd1 necesita producir una salida final que pueda leerse en la siguiente etapa para que rdd2 tenga exactamente 1000 particiones (¿Cómo lo hacen? Hash u Ordenar ). Las tareas en este lado a veces se denominan "tareas de mapa (lado)". Una tarea que luego se ejecutará en rdd2 actuará en una partición (¡de rdd2!) Y tendría que descubrir cómo leer / combinar las salidas del lado del mapa relevantes para esa partición. Las tareas de este lado a veces se denominan "tareas de reducción (de lado)".
Las 2 preguntas están relacionadas: el número de tareas en una etapa es el número de particiones (común a los rdds consecutivos "pegados" juntos) y el número de particiones de un rdd puede cambiar entre etapas (al especificar el número de particiones para algunos shuffle causando operación por ejemplo).
Una vez que comienza la ejecución de una etapa, sus tareas pueden ocupar espacios de tareas. El número de ranuras de tareas simultáneas es numExecutors * ExecutorCores. En general, estos pueden ser ocupados por tareas de diferentes etapas no dependientes.
fuente