Datos y bases de datos

El ecosistema Hadoop: HDFS, YARN, MapReduce, Hive, HBase y Spark

Intermedio11 min de lecturaActualizado

Esta página se tradujo del inglés con ayuda de IA y se cotejó con el original. Leer la versión en inglés

Hadoop introdujo la idea que marcó una década de ingeniería de datos: llevar el cómputo a los datos y asumir los fallos desde el diseño. Esta guía explica los bloques de HDFS y el NameNode, la planificación con YARN, MapReduce y los motivos por los que Spark lo desplazó, el papel de Hive y HBase, el modelo DataFrame de Spark y qué parte de la pila sigue teniendo sentido hoy.

Lo que aprenderás

  • Explicar cómo HDFS divide, replica y localiza los bloques y qué hace el NameNode
  • Describir cómo YARN asigna contenedores y cómo las aplicaciones solicitan recursos
  • Seguir un job de MapReduce por las fases map, shuffle y reduce, y explicar las ventajas de Spark
  • Elegir entre Hive, HBase y Spark según el patrón de acceso a los datos
  • Valorar qué partes del ecosistema aún merece la pena adoptar y qué ha sustituido al resto

La aportación de Hadoop no fue un software, sino una postura: dar por hecho que las máquinas son baratas y que van a fallar, repartir los datos entre ellas y enviar el cómputo allí donde ya están los datos. Eso invertía el supuesto de la generación anterior, en la que los datos se llevaban a una máquina grande y cara, e hizo posible analizar petabytes con hardware al alcance de empresas corrientes.

Dos décadas después, casi toda la implementación original ha quedado superada y, sin embargo, su vocabulario —bloques, shuffles, particiones, jobs, executors— sigue siendo el de la ingeniería de datos. Esta guía cuenta qué hace realmente cada componente, por qué Spark desplazó a MapReduce y qué piezas aún merecen un sitio en una plataforma de 2026. Las decisiones de arquitectura que los rodean —data lakes, formatos de tabla, streaming— se tratan en la guía de arquitectura big data.

HDFS: un sistema de archivos pensado para lecturas secuenciales

El Hadoop Distributed File System divide cada archivo en bloques de tamaño fijo, 128 MB por defecto, y guarda cada bloque en varias máquinas: tres por defecto, repartidas en al menos dos racks. Esa única decisión de diseño explica la mayor parte de su comportamiento.

El sistema funciona con dos tipos de proceso:

  • El NameNode mantiene en memoria todo el árbol de directorios y la correspondencia entre bloques y DataNodes, y registra cada cambio en un edit log. Nunca maneja él mismo los datos de los archivos: los clientes le preguntan dónde está un bloque y luego hablan directamente con los DataNodes.
  • Los DataNodes guardan los bloques como archivos normales en discos locales y se reportan mediante heartbeats e informes de bloques. Cuando un nodo deja de reportarse, el NameNode detecta que sus bloques están infrarreplicados y ordena a otros nodos que los copien.

La memoria del NameNode es el verdadero límite del sistema: cada archivo, directorio y bloque necesita un registro en memoria de unos 150 bytes. Por eso un millón de archivos pequeños cuesta muchísimo más que un único archivo grande del mismo tamaño total: es el problema de los archivos pequeños, con el que se ha topado todo administrador de Hadoop.

Del diseño se derivan tres propiedades que conviene decir con claridad. HDFS es write-once, append-only: no se puede actualizar in situ, así que los pipelines reescriben particiones enteras. Prioriza el throughput frente a la latencia, lo que lo convierte en una base de datos pésima y en un destino excelente para scans. Y es rack-aware: coloca las réplicas de forma que perder un rack entero no suponga perder datos y que los lectores puedan preferir una copia local.

Hadoop 3 trajo dos cambios importantes. La alta disponibilidad del NameNode ejecuta un NameNode activo y otro en espera que comparten los cambios a través de un quórum de JournalNodes, con ZooKeeper gestionando la conmutación por error; antes de eso, el NameNode era un auténtico punto único de fallo. Y el erasure coding guarda paridad en lugar de réplicas completas, lo que reduce la sobrecarga de almacenamiento del 200 % a alrededor del 50 % para datos fríos, a costa de más CPU y una recuperación más lenta.

hdfs dfs -put sales-2026-09.parquet /data/raw/sales/dt=2026-09-07/
hdfs dfs -ls -h /data/raw/sales/dt=2026-09-07/
hdfs fsck /data/raw/sales -files -blocks -locations
hdfs dfsadmin -report

YARN: planificar el clúster

Yet Another Resource Negotiator separa la gestión de recursos del clúster de la lógica de las aplicaciones que se ejecutan en él, y eso es lo que permitió ejecutar en un clúster Hadoop algo distinto de MapReduce.

  • El ResourceManager es el planificador de todo el clúster. Conoce la capacidad total y reparte contenedores, cada uno una reserva de memoria y CPU en un nodo concreto.
  • En cada máquina se ejecuta un NodeManager, que lanza contenedores e informa de su estado y su consumo.
  • Cada job enviado recibe primero un contenedor propio para su ApplicationMaster. Este negocia después más contenedores para el trabajo real, los supervisa y reinicia lo que falla. Así, la gestión de fallos a nivel de job vive en la aplicación, no en el planificador.

En la práctica importan dos planificadores. El Capacity Scheduler divide el clúster en colas jerárquicas con cuotas garantizadas y elasticidad opcional, lo que encaja en organizaciones donde los departamentos tienen capacidad contratada. El Fair Scheduler intenta dar a cada aplicación en ejecución una parte igual a lo largo del tiempo, lo que encaja con cargas ad hoc variadas. En ambos casos, la lección operativa que se repite es la misma: un solo job mal dimensionado que pide contenedores enormes puede dejar sin recursos a todo lo demás, así que los límites de cola y los topes por usuario no son opcionales.

MapReduce, y por qué Spark lo sustituyó

MapReduce expresa el cómputo como dos funciones con una ordenación entre ambas.

  1. Map se ejecuta sobre cada split de entrada —normalmente un bloque de HDFS, planificado en un nodo que lo contiene— y emite pares clave-valor.
  2. Shuffle y ordenación envía cada par al reducer responsable de su clave, ordenando por clave por el camino. Es la parte cara: atraviesa la red y vuelca a disco.
  3. Reduce recibe cada clave con todos sus valores y emite el resultado.

El conteo de palabras es el ejemplo canónico: map emite (word, 1) por cada token y reduce suma los valores por palabra. El modelo es realmente elegante, y la misma forma de map seguido de reduce aparece en código de aplicación corriente: la API Streams de Java es la versión de una sola máquina de la misma idea.

Sus debilidades son estructurales, no estéticas:

  • Cada etapa se materializa en disco. Un pipeline de cinco transformaciones escribe y vuelve a leer el conjunto de datos completo cinco veces, con replicación en cada escritura.
  • Los algoritmos iterativos son patológicos. Los algoritmos de machine learning y de grafos recorren los mismos datos decenas de veces y pagan en cada pasada el coste completo de E/S.
  • Solo dos operadores. Joins, filtros, agregaciones y ordenaciones hay que construirlos a mano a partir de map y reduce, así que los jobs reales acabaron siendo largas cadenas de clases Java.
  • Solo batch. Ni consultas interactivas ni streaming.

Apache Spark resolvió los cuatro problemas con un único cambio de modelo: mantener el conjunto de datos en memoria entre etapas y describir todo el cómputo como un grafo acíclico dirigido (DAG) de transformaciones antes de ejecutar nada. Así Spark puede fusionar las transformaciones estrechas en una sola pasada, introducir un shuffle solo donde los datos tienen que redistribuirse de verdad y reutilizar datos en caché entre iteraciones. Las aceleraciones anunciadas —de diez a cien veces frente a MapReduce— venían sobre todo de eliminar las escrituras intermedias, no de ninguna aritmética ingeniosa.

El modelo de programación de Spark

La abstracción original de Spark era el RDD, un resilient distributed dataset: una colección inmutable y particionada con el linaje registrado de las operaciones que la produjeron. El linaje es su mecanismo de recuperación: una partición perdida se recalcula a partir de sus padres en lugar de restaurarse desde una réplica. Las transformaciones (map, filter, join) son perezosas; no se ejecuta nada hasta que una acción (count, collect, write) fuerza la evaluación.

El código Spark moderno debería usar DataFrames y Datasets. Llevan un esquema, lo que permite al optimizador Catalyst reescribir la consulta —empujando los filtros hasta el scan, descartando las columnas que no se leen, eligiendo la estrategia de join— y al motor Tungsten guardar las filas en memoria off-heap compacta y generar bytecode especializado. La consecuencia práctica es que un pipeline con DataFrames suele superar al código RDD escrito a mano, igual que el SQL declarativo supera a un bucle escrito a mano.

val orders = spark.read.parquet("s3a://lake/curated/orders")
val customers = spark.read.parquet("s3a://lake/curated/customers")

val topRegions = orders
  .filter($"placed_at" >= "2026-01-01" && $"status" === "SHIPPED")
  .join(customers.select($"id", $"region"), $"customer_id" === $"id")
  .groupBy($"region")
  .agg(sum($"total").as("revenue"), countDistinct($"customer_id").as("buyers"))
  .orderBy($"revenue".desc)

topRegions.explain(true)          // read the physical plan before trusting the job
topRegions.write.mode("overwrite").parquet("s3a://lake/serving/revenue_by_region")

Spark SQL ejecuta el mismo motor sobre texto SQL, de modo que analistas e ingenieros comparten una única ruta de ejecución. Structured Streaming reutiliza la API de DataFrames para entradas no acotadas, con ventanas por event time y estado guardado mediante checkpoints. Spark 4 siguió en la misma dirección: la semántica ANSI SQL es ahora la predeterminada, así que los desbordamientos silenciosos y los truncamientos implícitos pasan a ser errores; Spark Connect desacopla el cliente del driver, lo que permite a clientes ligeros enviar trabajo a un clúster remoto; y un tipo nativo VARIANT maneja datos semiestructurados sin hacer explotar el esquema.

Tres conceptos de rendimiento explican la mayor parte del tuning de Spark:

  • Las particiones son la unidad de paralelismo. Si hay pocas, los núcleos se quedan ociosos; si hay demasiadas, domina la sobrecarga de planificación. La adaptive query execution ya las fusiona automáticamente en los límites de shuffle.
  • Los shuffles son la operación cara. Las transformaciones anchas (groupBy, join, distinct) los provocan; las estrechas, no. Un broadcast join evita el shuffle por completo cuando uno de los lados es lo bastante pequeño como para caber en la memoria de cada executor.
  • El skew —una clave que acapara una proporción desmedida de filas— deja una única tarea ejecutándose mucho después de que terminen las demás. La adaptive execution puede dividir las particiones desequilibradas; salar la clave es el remedio manual.

Hive y HBase

Apache Hive puso SQL encima de archivos. Una consulta en HiveQL se compila en un job —históricamente MapReduce, después Tez y a menudo Spark— sobre datos en HDFS o en almacenamiento de objetos. Su aportación duradera no es el motor de consultas, sino el Metastore: una base de datos relacional que registra qué tablas existen, sus columnas y tipos, sus particiones y la ubicación de sus archivos. Ese catálogo sobrevivió al propio Hive; Spark, Trino, Flink e Impala lo leen, y sigue siendo un punto de interoperabilidad habitual incluso en clústeres sin rastro de Hadoop.

Hive tiene las características de un motor de scan: throughput alto, latencias de minutos en los jobs grandes, ningún índice digno de ese nombre y un soporte ACID añadido a posteriori que conviene evitar en favor de un formato de tabla moderno. LLAP añadió demonios de larga duración y caché para acercar las consultas interactivas, aunque la mayoría de los equipos ahora apuntan Trino o Spark SQL al mismo metastore.

Apache HBase es la herramienta opuesta: un almacén de columnas anchas inspirado en Bigtable, que se ejecuta sobre HDFS y ofrece lecturas y escrituras aleatorias de milisegundos por clave de fila. Los datos se organizan en familias de columnas, se dividen en regiones por rangos de clave de fila y los sirven los RegionServers; las escrituras pasan por un write-ahead log y un almacén en memoria que se vuelca a archivos inmutables, compactados en segundo plano.

Usar bien HBase se reduce por completo al diseño de la clave de fila. Las claves se guardan ordenadas, así que una clave monótonamente creciente (una marca de tiempo, una secuencia) envía todas las escrituras a una sola región: es el problema del hotspotting, que se resuelve salando o aplicando un hash a un prefijo. A la inversa, una clave que empieza por el valor por el que recorres los datos hace eficientes los scans por rango. No hay índices secundarios, ni joins, ni planificador de consultas: o diseñas la clave para el patrón de acceso, o lo recorres todo. Para comparar con el enfoque documental ante el mismo compromiso, consulta la guía de MongoDB.

A su alrededor están el resto de nombres conocidos: Sqoop para transferencias masivas entre bases de datos relacionales y HDFS, desplazado en gran medida por el change data capture hacia un broker, como se describe en la arquitectura de Kafka; Oozie para orquestar workflows, desplazado por Airflow y planificadores similares; Impala y Presto/Trino para SQL MPP interactivo; ZooKeeper para la coordinación, por debajo de varios de los anteriores; y Apache Ozone, un almacén de objetos más reciente diseñado para superar los límites de HDFS con los archivos pequeños y la escala.

Cómo está el ecosistema en 2026

El resumen honesto es que las ideas ganaron y casi toda la implementación se sustituyó.

  • HDFS está en modo mantenimiento en la mayoría de las organizaciones. El almacenamiento de objetos en la nube ofrece una capacidad prácticamente ilimitada, separa almacenamiento y cómputo para que cada uno escale por su cuenta y cuesta menos. Spark y Trino lo leen directamente mediante el conector S3A.
  • MapReduce es legacy. No debería escribirse nada nuevo sobre él; los jobs existentes se migran a Spark.
  • YARN persiste on-premise, pero los nuevos despliegues planifican Spark sobre Kubernetes de forma abrumadora, lo que unifica el modelo operativo con el resto de la plataforma: contenedores, imágenes y orquestación, como se explica en los fundamentos de Docker.
  • Hive como motor ha cedido en gran medida el terreno a Trino, Spark SQL y los data warehouses en la nube; el Metastore sobrevive, aunque los catálogos REST de Iceberg lo están reemplazando poco a poco.
  • HBase sigue donde se desplegó, mientras Cassandra, ScyllaDB y los almacenes clave-valor gestionados en la nube se quedan con las cargas nuevas.
  • Spark está en plena forma, y es la pieza del ecosistema que más merece la pena aprender hoy.

Si heredas un clúster Hadoop, el camino pragmático suele ser: llevar el almacenamiento a almacenamiento de objetos con un formato de tabla abierto, migrar los jobs de MapReduce a Spark, mantener el metastore como catálogo hasta que lo sustituya un catálogo de Iceberg y cambiar el planificador de YARN a Kubernetes. Si empiezas de cero, casi seguro que necesitas Spark y un formato de tabla, y casi seguro que no necesitas HDFS.

Puntos clave

  • HDFS guarda bloques grandes, replicados e inmutables para maximizar el throughput secuencial; los metadatos que el NameNode mantiene en memoria explican por qué los archivos pequeños hacen tanto daño.
  • YARN separa la gestión de recursos de la lógica de las aplicaciones mediante el ResourceManager, los NodeManagers y un ApplicationMaster por job que solicita contenedores.
  • El modelo map-shuffle-reduce de MapReduce es sólido, pero materializa cada etapa en disco, y eso es lo que hizo que la ejecución en memoria basada en DAG de Spark fuera diez veces más rápida o más.
  • Prefiere los DataFrames de Spark a los RDD para que Catalyst y Tungsten puedan optimizar; haz el tuning vigilando particiones, shuffles y skew.
  • Hive es una capa SQL orientada a scans cuyo Metastore le sobrevivió; HBase es un almacén de columnas anchas de acceso aleatorio en el que el diseño de la clave de fila lo determina todo.
  • En 2026, quédate con Spark y con la idea de catálogo, migra el almacenamiento a almacenamiento de objetos con un formato de tabla abierto y planifica sobre Kubernetes en lugar de YARN.

Fuentes y lecturas recomendadas

Preguntas frecuentes

¿Está muerto Hadoop?
MapReduce como modelo de programación prácticamente sí, y pocos proyectos nuevos despliegan HDFS. Pero las ideas del ecosistema y varios de sus componentes siguen vivos: el Hive Metastore sigue catalogando tablas para motores que nunca tocan Hadoop, YARN sigue planificando clústeres on-premise y Spark, que creció dentro del ecosistema, se usa más que nunca. Trátalo como infraestructura que hay que entender y heredar, no como base para construir algo nuevo.
¿Por qué el tamaño de bloque de HDFS es de 128 MB?
Porque un bloque grande amortiza el coste de los posicionamientos. Con bloques pequeños, un job pasa la mayor parte del tiempo moviendo los cabezales del disco y preguntando al NameNode dónde está cada cosa; con bloques grandes, lee en flujo continuo. Los bloques grandes también mantienen a raya la memoria del NameNode, porque cada bloque necesita un registro en memoria. La contrapartida es que muchos archivos pequeños desperdician tanto metadatos de bloques como tiempo de planificación.
¿Qué diferencia hay entre Hive y HBase?
Resuelven problemas opuestos. Hive es una capa SQL sobre archivos masivos para consultas analíticas de recorrido completo que tardan de segundos a minutos, sin ninguna noción de actualización puntual. HBase es un almacén de columnas anchas para lecturas y escrituras aleatorias de milisegundos por clave de fila, sin planificador de consultas ni joins. Usar cualquiera de los dos para la carga de trabajo del otro solo trae decepciones.
¿Debo ejecutar Spark sobre YARN o sobre Kubernetes?
Kubernetes para todo lo nuevo. Te da el mismo aislamiento por contenedores que ya usan tus demás cargas de trabajo, un único modelo operativo para toda la plataforma y escalado elástico sobre instancias en la nube. YARN sigue siendo una opción razonable donde ya existe un clúster Hadoop on-premise y su Capacity Scheduler codifica políticas multi-tenant reales que, de otro modo, tendrías que reconstruir.