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.

  1. 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).

  1. 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.

  1. 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

  1. Crear una sesión de Spark: Inicializamos una sesión de Spark.
  2. Crear un DataFrame: Creamos un DataFrame con datos de ejemplo.
  3. Transformación: Aplicamos un filtro para seleccionar personas mayores de 30 años.
  4. Acción: Contamos el número de filas que cumplen con el filtro.
  5. 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.

  1. 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

  1. Crear una sesión de Spark: Inicializamos una sesión de Spark.
  2. Crear un DataFrame: Creamos un DataFrame con datos de ventas de productos.
  3. Transformación (filter): Filtramos los productos con ventas mayores a 100 unidades.
  4. Acción (groupBy().sum("Ventas")): Calculamos el total de ventas de los productos filtrados.
  5. Detener la sesión de Spark: Cerramos la sesión de Spark.

  1. 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.

© Copyright 2024. Todos los derechos reservados