Apache Spark

Arquitectura de Apache Spark: Una Guía Completa

11 min lectura José Miguel

Apache Spark se ha convertido en una herramienta fundamental en el ecosistema del Big Data, revolucionando la forma en que procesamos grandes volúmenes de información. Su arquitectura robusta y eficiente permite analizar datos a velocidades impresionantes, superando significativamente a tecnologías anteriores como Hadoop. En este artículo, exploraremos en detalle la arquitectura de Apache Spark.

¿Qué es Apache Spark?

Apache Spark es un framework de código abierto diseñado para la computación en clúster que ha transformado la industria del Big Data. Este sistema permite procesar grandes volúmenes de datos de manera distribuida, ofreciendo un rendimiento aproximadamente 100 veces más rápido en operaciones en memoria y 10 veces más rápido en operaciones en disco en comparación con Hadoop. Su diseño basado en capas permite que todos sus componentes estén acoplados de manera flexible, facilitando su extensibilidad y mantenimiento.

Características principales de Apache Spark

Antes de profundizar en su arquitectura, es importante conocer las características que hacen destacar a Spark:

  • Velocidad superior: Gracias a su capacidad de procesamiento en memoria y particionamiento controlado, Spark logra un rendimiento excepcional al procesar grandes volúmenes de datos.
  • Procesamiento en tiempo real: Ofrece computación en tiempo real y baja latencia gracias a su análisis en memoria, lo que lo hace ideal para aplicaciones que requieren respuestas inmediatas.
  • Potente sistema de caché: Cuenta con una capa de programación superficial que proporciona capacidades potentes de almacenamiento en caché y persistencia en disco.
  • Versatilidad de lenguajes: Soporta múltiples lenguajes de programación como Python, Scala, Java y R, lo que facilita su adopción por desarrolladores con diferentes habilidades.

Arquitectura de Apache Spark: visión general

La arquitectura de Apache Spark está diseñada siguiendo un modelo maestro-esclavo, donde un nodo maestro coordina la distribución y ejecución de tareas en múltiples nodos trabajadores. Esta estructura permite el procesamiento paralelo de datos a gran escala, optimizando el rendimiento y la eficiencia.

Arquitectura Apache Spark
Arquitectura Apache Spark

Componentes principales

La arquitectura de Apache Spark se compone de tres elementos fundamentales:

  1. Spark Driver (Controlador)
  2. Spark Executors (Ejecutores)
  3. Cluster Manager (Gestor de clúster)

Veamos cada uno en detalle:

Spark Driver

El Spark Driver actúa como el centro de control de la aplicación. Como su nombre indica, ocupa el «asiento del conductor» y controla la ejecución de la aplicación. Sus principales responsabilidades incluyen:

  • Mantener todos los estados de las aplicaciones que se ejecutan en el clúster de Spark
  • Traducir el código escrito por el usuario en jobs que luego se ejecutan en el clúster
  • Crear el SparkContext, que contiene todas las funcionalidades básicas
  • Dividir los jobs en tareas más pequeñas para distribuirlas a los nodos trabajadores
  • Comunicarse con el gestor de clúster para obtener recursos físicos y lanzar ejecutores

Spark Executors

Los ejecutores son procesos que se ejecutan en los nodos trabajadores del clúster y son responsables de:

  • Ejecutar las tareas asignadas por el Spark Driver
  • Informar sobre el éxito o fracaso de las tareas y devolver los resultados al controlador
  • Proporcionar almacenamiento en memoria para RDDs que son cacheados por aplicaciones del usuario
  • Cada aplicación tiene sus propios procesos ejecutores, lo que garantiza el aislamiento entre aplicaciones

Cluster Manager

El gestor de clúster es el componente que adquiere y gestiona los recursos en el clúster. Spark puede trabajar con varios gestores de clúster como:

  • Standalone (incluido en Spark)
  • Apache Mesos
  • Apache Hadoop YARN
  • Kubernetes

El gestor de clúster tiene su propio controlador y abstracciones de trabajadores que están vinculados a máquinas físicas, a diferencia de los procesos de Spark.

Modos de implementación

Apache Spark ofrece diferentes modos para ejecutar aplicaciones, adaptándose a distintos escenarios y necesidades:

Cluster Mode (Modo Clúster)

Es uno de los modos más comunes para ejecutar aplicaciones Spark. En este modo:

  • El usuario envía un archivo precompilado (JAR, script Python o R) al gestor de clúster
  • El proceso del controlador se lanza en un nodo trabajador dentro del clúster
  • El gestor de clúster también ayuda a lanzar los procesos ejecutores
  • Todas las operaciones relacionadas con la aplicación Spark son gestionadas por el clúster, lo que lo hace ideal para aplicaciones de producción

Client Mode (Modo Cliente)

Similar al modo clúster, pero con una diferencia fundamental:

  • El proceso del Spark Driver se mantiene en la máquina cliente que envió la aplicación
  • La máquina cliente mantiene el proceso del Spark Driver, mientras que el gestor de clúster mantiene los procesos ejecutores
  • Útil para aplicaciones interactivas o durante el desarrollo, ya que permite interactuar directamente con la aplicación

Comparativa de modos de despliegue

CaracterísticaCluster ModeClient Mode
Ubicación del DriverNodo trabajador del clústerMáquina cliente
Caso de usoProducciónDesarrollo / interactivo
Dependencia de redBaja (todo en el clúster)Alta (cliente debe estar conectado)
Acceso a logsA través del Cluster ManagerDirectamente en consola
Tolerancia a fallos del clienteLa app sigue si el cliente se desconectaLa app falla si el cliente se desconecta

Abstracciones principales de Apache Spark

La base de la arquitectura de Spark se sustenta en dos abstracciones fundamentales:

Resilient Distributed Datasets (RDD)

Los RDD son la estructura de datos fundamental y primitiva en Spark. Representan colecciones de objetos distribuidos e inmutables que pueden procesarse en paralelo. Características clave:

  • Inmutabilidad: Una vez creados, no pueden ser modificados
  • Distribución: Los datos se distribuyen a través de múltiples nodos
  • Resiliencia: Capacidad de recalcular los datos si hay fallos, manteniendo un linaje de operaciones
  • Evaluación perezosa: Las transformaciones no se ejecutan hasta que se solicita una acción

Ejemplo básico de creación y transformación de un RDD en PySpark:

from pyspark import SparkContext

sc = SparkContext("local", "EjemploRDD")

# Crear un RDD a partir de una lista
datos = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
rdd = sc.parallelize(datos)

# Transformaciones (evaluación perezosa)
rdd_pares = rdd.filter(lambda x: x % 2 == 0)
rdd_cuadrados = rdd_pares.map(lambda x: x ** 2)

# Acción (dispara la ejecución)
resultado = rdd_cuadrados.collect()
print(resultado)  # [4, 16, 36, 64, 100]

sc.stop()

Directed Acyclic Graph (DAG)

El DAG es el modelo de ejecución de Spark:

  • Para cada job, el controlador convierte el programa en un DAG
  • Representa una secuencia de cálculos que se deben realizar
  • Es un grafo dirigido sin ciclos: las operaciones fluyen en una dirección sin volver atrás
  • Permite a Spark optimizar la ejecución mediante la reorganización de operaciones y la minimización de transferencias de datos

Ecosistema de Apache Spark

El ecosistema de Spark está compuesto por diferentes componentes integrados que amplían sus capacidades:

ComponentePropósitoCaso de uso típico
Spark CoreMotor de ejecución baseProgramación distribuida, gestión de tareas
Spark SQLDatos estructuradosConsultas SQL sobre DataFrames
Spark StreamingDatos en tiempo realProcesamiento de flujos continuos
MLlibAprendizaje automáticoEntrenamiento de modelos escalables
GraphXProcesamiento de grafosAnálisis de redes, PageRank

Spark Core

Es el motor de ejecución subyacente en el que se basan todos los demás componentes. Proporciona:

  • Programación distribuida
  • Gestión de tareas
  • E/S básicas

Spark SQL

Módulo para trabajar con datos estructurados:

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("EjemploSQL").getOrCreate()

# Crear un DataFrame a partir de un archivo CSV
df = spark.read.csv("ventas.csv", header=True, inferSchema=True)

# Registrar como vista temporal para usar SQL
df.createOrReplaceTempView("ventas")

# Consulta SQL
resultado = spark.sql("""
    SELECT categoria, 
           SUM(monto) AS total_ventas,
           COUNT(*) AS num_transacciones
    FROM ventas
    WHERE año = 2024
    GROUP BY categoria
    ORDER BY total_ventas DESC
""")

resultado.show()

Spark Streaming

Permite el procesamiento de datos en tiempo real:

from pyspark.sql import SparkSession
from pyspark.sql.functions import window, col, count

spark = SparkSession.builder.appName("EjemploStreaming").getOrCreate()

# Leer flujo de datos desde un socket
lineas = spark.readStream \
    .format("socket") \
    .option("host", "localhost") \
    .option("port", 9999) \
    .load()

# Contar palabras en ventanas de 10 segundos
palabras = lineas.select(col("value").alias("palabra"))
conteo = palabras.groupBy("palabra").count()

# Escribir resultados en consola
query = conteo.writeStream \
    .outputMode("complete") \
    .format("console") \
    .start()

query.awaitTermination()

MLlib

Biblioteca de aprendizaje automático de Spark que ofrece algoritmos escalables:

from pyspark.ml.classification import LogisticRegression
from pyspark.ml.feature import VectorAssembler
from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("EjemploMLlib").getOrCreate()

# Cargar datos de entrenamiento
datos = spark.read.csv("dataset.csv", header=True, inferSchema=True)

# Preparar features con VectorAssembler
assembler = VectorAssembler(
    inputCols=["edad", "salario", "experiencia"],
    outputCol="features"
)
datos_preparados = assembler.transform(datos)

# Entrenar modelo de regresión logística
lr = LogisticRegression(featuresCol="features", labelCol="etiqueta")
modelo = lr.fit(datos_preparados)

# Evaluar el modelo
predicciones = modelo.transform(datos_preparados)
predicciones.select("features", "etiqueta", "prediction").show()

GraphX

Componente para el procesamiento de gráficos y análisis de redes:

import org.apache.spark.graphx._
import org.apache.spark.rdd.RDD

// Definir vértices (id, nombre)
val vertices: RDD[(VertexId, String)] = sc.parallelize(Seq(
  (1L, "Alice"), (2L, "Bob"), (3L, "Charlie"), (4L, "Diana")
))

// Definir aristas (origen, destino, relación)
val aristas: RDD[Edge[String]] = sc.parallelize(Seq(
  Edge(1L, 2L, "amigo"),
  Edge(2L, 3L, "colega"),
  Edge(3L, 4L, "amigo"),
  Edge(4L, 1L, "colega")
))

// Crear el grafo
val grafo = Graph(vertices, aristas)

// Ejecutar PageRank
val ranks = grafo.pageRank(0.001).vertices
ranks.collect().foreach { case (id, rank) =>
  println(s"Vértice $id tiene rank: $rank")
}

Flujo de trabajo en la arquitectura de Spark

Veamos cómo funciona Apache Spark desde que enviamos un trabajo hasta que recibimos los resultados:

  1. El usuario envía una aplicación al clúster
  2. El controlador (Spark Driver) traduce esta aplicación en un DAG de operaciones
  3. El DAG se divide en etapas que representan conjuntos de tareas que se pueden ejecutar en paralelo
  4. Las etapas se dividen en tareas individuales
  5. El controlador coordina con el gestor de clúster para asignar las tareas a los ejecutores
  6. Los ejecutores procesan las tareas y almacenan los resultados en memoria o disco según sea necesario
  7. Si ocurren fallos, las tareas pueden redistribuirse automáticamente a otros ejecutores
  8. Una vez completadas todas las tareas, los resultados se devuelven al controlador y, finalmente, al usuario

Casos de uso prácticos de Apache Spark

Apache Spark es versátil y se utiliza en numerosos escenarios:

Análisis de Big Data

Ideal para procesar y analizar grandes volúmenes de datos estructurados y no estructurados, como registros web, datos de sensores o transacciones comerciales.

Aprendizaje automático

MLlib permite entrenar modelos con grandes conjuntos de datos:

  • Clasificación y regresión para predicciones
  • Clustering para segmentación de datos
  • Sistemas de recomendación para personalización

Procesamiento en tiempo real

Spark Streaming facilita el análisis de datos en movimiento, como:

  • Detección de fraudes en tiempo real
  • Monitoreo de sistemas
  • Análisis de sentimientos en redes sociales

Análisis de grafos

GraphX permite realizar análisis de redes sociales, detección de comunidades y cálculo de rutas óptimas.

Primeros pasos con Apache Spark

Para comenzar a trabajar con Apache Spark, puedes iniciar una sesión interactiva con pyspark o enviar aplicaciones al clúster con spark-submit:

# Iniciar una sesión interactiva de PySpark
pyspark --master local[*]

# Enviar una aplicación al clúster en modo cluster
spark-submit \
    --master yarn \
    --deploy-mode cluster \
    --num-executors 4 \
    --executor-memory 4g \
    --executor-cores 2 \
    mi_aplicacion.py

# Enviar una aplicación en modo client
spark-submit \
    --master yarn \
    --deploy-mode client \
    mi_aplicacion.py

Conclusión

La arquitectura de Apache Spark representa un avance significativo en el procesamiento de datos a gran escala. Su diseño en capas, con componentes acoplados de manera flexible, permite un procesamiento distribuido eficiente y rápido. Las abstracciones fundamentales como RDDs y DAGs proporcionan la base para operaciones complejas, mientras que los diferentes módulos del ecosistema Spark amplían sus capacidades para cubrir prácticamente cualquier necesidad de procesamiento de datos.

La combinación de velocidad, capacidad de procesamiento en tiempo real y versatilidad hace de Apache Spark una herramienta indispensable en el arsenal de cualquier profesional de datos. Ya sea para análisis de big data, aprendizaje automático o procesamiento de flujos en tiempo real, Spark ofrece un framework robusto y eficiente que continuará siendo relevante en los próximos años.

Para quienes están comenzando con Apache Spark, comprender su arquitectura es el primer paso para aprovechar todo su potencial. A medida que se familiaricen con sus componentes y funcionamiento, podrán desarrollar aplicaciones más eficientes y efectivas para resolver problemas de datos del mundo real.

José Miguel Moya Curbelo
José Miguel Moya Curbelo
Senior Data Engineer & Big Data Instructor

MSc Applied Mathematics · AWS Cloud Practitioner · SCRUM Master. Especializado en arquitecturas de datos de alto rendimiento con Apache Spark, Snowflake, Python y Scala.

Conectar en LinkedIn

Artículos Relacionados