En este módulo, profundizaremos en cómo Apache Spark maneja los trabajos (jobs) y las tareas (tasks). Comprender cómo Spark ejecuta y organiza el procesamiento de datos es crucial para optimizar el rendimiento y solucionar problemas en aplicaciones Spark.
- Conceptos Clave
1.1. Job (Trabajo)
Un trabajo en Spark es una unidad de trabajo que se ejecuta como resultado de una acción (como collect(), save(), count(), etc.) en un RDD o DataFrame. Cada trabajo se divide en etapas (stages) y tareas (tasks).
1.2. Stage (Etapa)
Un trabajo se divide en una o más etapas. Cada etapa representa un conjunto de tareas que pueden ejecutarse en paralelo. Las etapas se determinan por las dependencias de ancho estrecho (narrow dependencies) y ancho amplio (wide dependencies).
1.3. Task (Tarea)
Una tarea es la unidad más pequeña de trabajo en Spark. Cada tarea se ejecuta en un solo fragmento de datos (partition) y se asigna a un ejecutor (executor).
- Ejecución de un Trabajo en Spark
2.1. Planificación de un Trabajo
Cuando se ejecuta una acción en un RDD o DataFrame, Spark crea un plan de ejecución lógico. Este plan se convierte en un plan físico que se divide en etapas y tareas.
2.2. Dependencias
- Narrow Dependencies (Dependencias Estrechas): Cada partición de un RDD depende de una partición de su RDD padre. Ejemplo:
map(),filter(). - Wide Dependencies (Dependencias Amplias): Cada partición de un RDD depende de múltiples particiones de su RDD padre. Ejemplo:
groupByKey(),reduceByKey().
2.3. DAG (Directed Acyclic Graph)
Spark representa el plan de ejecución como un DAG. Cada nodo en el DAG representa un RDD y cada borde representa una transformación.
- Ejemplo Práctico
Veamos un ejemplo práctico para entender cómo Spark maneja los trabajos.
from pyspark.sql import SparkSession
# Crear una sesión de Spark
spark = SparkSession.builder.appName("EntendiendoTrabajosSpark").getOrCreate()
# Crear un DataFrame de ejemplo
data = [("Alice", 34), ("Bob", 45), ("Cathy", 29)]
columns = ["Nombre", "Edad"]
df = spark.createDataFrame(data, columns)
# Realizar una transformación y una acción
df_filtered = df.filter(df["Edad"] > 30)
count = df_filtered.count()
print(f"El número de personas mayores de 30 años es: {count}")
# Detener la sesión de Spark
spark.stop()Explicación del Código
- Crear una sesión de Spark: Inicializamos una sesión de Spark.
- Crear un DataFrame: Creamos un DataFrame con datos de ejemplo.
- Transformación: Aplicamos un filtro para seleccionar personas mayores de 30 años.
- Acción: Contamos el número de filas que cumplen con el filtro.
- Detener la sesión de Spark: Cerramos la sesión de Spark.
Análisis del Trabajo
- Transformación (
filter): Esta operación crea un nuevo DataFrame pero no ejecuta ninguna computación hasta que se llama a una acción. - Acción (
count): Esta operación desencadena la ejecución del trabajo. Spark crea un DAG, lo divide en etapas y ejecuta las tareas correspondientes.
- Ejercicio Práctico
Ejercicio
Crea un DataFrame con datos de ventas de productos. Filtra los productos con ventas mayores a 100 unidades y calcula el total de ventas de estos productos.
# Crear una sesión de Spark
spark = SparkSession.builder.appName("EjercicioTrabajosSpark").getOrCreate()
# Crear un DataFrame de ejemplo
data = [("ProductoA", 150), ("ProductoB", 80), ("ProductoC", 200)]
columns = ["Producto", "Ventas"]
df = spark.createDataFrame(data, columns)
# Realizar una transformación y una acción
df_filtered = df.filter(df["Ventas"] > 100)
total_ventas = df_filtered.groupBy().sum("Ventas").collect()[0][0]
print(f"El total de ventas de productos con más de 100 unidades es: {total_ventas}")
# Detener la sesión de Spark
spark.stop()Solución
- Crear una sesión de Spark: Inicializamos una sesión de Spark.
- Crear un DataFrame: Creamos un DataFrame con datos de ventas de productos.
- Transformación (
filter): Filtramos los productos con ventas mayores a 100 unidades. - Acción (
groupBy().sum("Ventas")): Calculamos el total de ventas de los productos filtrados. - Detener la sesión de Spark: Cerramos la sesión de Spark.
- Resumen
En esta sección, hemos aprendido sobre la estructura y ejecución de trabajos en Apache Spark. Hemos cubierto conceptos clave como trabajos, etapas y tareas, y hemos visto cómo Spark organiza y ejecuta estos trabajos utilizando un DAG. Además, hemos trabajado con ejemplos prácticos para reforzar estos conceptos.
En el próximo módulo, exploraremos cómo utilizar caché y persistencia para optimizar el rendimiento de nuestras aplicaciones Spark.
Curso de Apache Spark
Módulo 1: Introducción a Apache Spark
Módulo 2: Conceptos Básicos de Spark
- RDDs (Conjuntos de Datos Distribuidos Resilientes)
- Transformaciones y Acciones
- DataFrames de Spark
- Spark SQL
Módulo 3: Procesamiento de Datos con Spark
Módulo 4: Programación Avanzada en Spark
Módulo 5: Ajuste y Optimización del Rendimiento
- Entendiendo los Trabajos de Spark
- Caché y Persistencia
- Gestión de Memoria
- Optimizando Aplicaciones Spark
Módulo 6: Spark en la Nube
- Ejecutando Spark en AWS
- Ejecutando Spark en Azure
- Ejecutando Spark en Google Cloud
- Spark con Kubernetes
Módulo 7: Aplicaciones del Mundo Real y Estudios de Caso
- Procesamiento de Datos en Tiempo Real
- Analítica de Big Data
- Pipelines de Aprendizaje Automático
- Estudios de Caso
