🦅 Capítulo 8 · Nivel Avanzado

Ecosistema Apache

El ecosistema de Apache Software Foundation es el fundamento histórico del Big Data. Entender Hadoop, HDFS, Hive y los formatos de archivo modernos es esencial para cualquier Data Engineer senior.

⏱️ Lectura: ~55 min
🎯 Nivel: Avanzado
📌 Foco: Fundamentos + Modernidad

Hadoop y HDFS

Apache Hadoop fue el sistema que democratizó el Big Data entre 2006 y 2018. Aunque hoy está siendo reemplazado por soluciones cloud, entender su arquitectura es fundamental para comprender cómo evolucionó la industria.

La Arquitectura de Hadoop

graph TD subgraph "HDFS - Almacenamiento Distribuido" NN[🎯 NameNode
Metadata & Namespace
Maestro único] DN1[💾 DataNode 1
Bloques de datos] DN2[💾 DataNode 2
Bloques de datos] DN3[💾 DataNode 3
Bloques de datos] NN --> DN1 NN --> DN2 NN --> DN3 end subgraph "YARN - Gestión de Recursos" RM[⚙️ Resource Manager
Maestro de recursos] NM1[📦 Node Manager 1] NM2[📦 Node Manager 2] NM3[📦 Node Manager 3] RM --> NM1 RM --> NM2 RM --> NM3 end subgraph "Aplicaciones" APP[MapReduce / Spark / Hive] end APP --> RM NM1 --- DN1 NM2 --- DN2 NM3 --- DN3 style NN fill:#7c2d12,stroke:#f97316,color:#fff style RM fill:#1e3a5f,stroke:#3b82f6,color:#fff

HDFS: Conceptos Clave

# ── COMANDOS HDFS ESENCIALES ───────────────────────────────────────────────
# HDFS usa una API similar a Linux filesystem

# Listar archivos
hdfs dfs -ls /user/de/data/
hdfs dfs -ls -R /warehouse/  # Recursivo

# Subir/bajar archivos
hdfs dfs -put local_file.csv /user/de/data/
hdfs dfs -get /user/de/data/output.parquet ./local_output.parquet

# Ver contenido
hdfs dfs -cat /user/de/data/file.csv | head -20
hdfs dfs -tail /user/de/logs/app.log

# Crear directorios y gestión
hdfs dfs -mkdir -p /warehouse/database/table/
hdfs dfs -cp /source/path /destination/path
hdfs dfs -mv /old/path /new/path
hdfs dfs -rm -r /path/to/delete/

# Información sobre archivos y bloques
hdfs dfs -du -h /warehouse/  # Disk usage human-readable
hdfs fsck /warehouse/orders/ -files -blocks  # Verificar integridad
hdfs dfsadmin -report  # Estado del cluster

# Configuración de replicación
hdfs dfs -setrep -w 2 /user/de/large-table/  # Reducir a 2 réplicas
⚠️ Estado de Hadoop en 2026

Hadoop on-premise está en declive. La mayoría de empresas ha migrado a cloud storage (S3, GCS, ADLS) que son más económicos, no requieren operación de clusters y tienen mejor disponibilidad. Sin embargo, muchas empresas enterprise todavía tienen Hadoop en producción, y los conceptos (bloques, replicación, data locality) son útiles para entender cómo funcionan los sistemas distribuidos modernos.

Apache Hive

Hive convirtió HDFS en un Data Warehouse al agregar una capa SQL sobre MapReduce/Spark. Fue la primera solución que permitió a analistas consultar petabytes de datos con SQL estándar.

-- ── HIVE SQL: Crear tablas sobre archivos HDFS ─────────────────────────────
-- Tabla externa: Hive solo define el esquema, los datos quedan en HDFS
CREATE EXTERNAL TABLE IF NOT EXISTS sales (
    sale_id     BIGINT,
    customer_id INT,
    amount      DOUBLE,
    sale_date   STRING
)
ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    LINES TERMINATED BY '\n'
STORED AS TEXTFILE
LOCATION '/warehouse/raw/sales/'
TBLPROPERTIES ("skip.header.line.count"="1");

-- Tabla particionada y en formato columnar (mucho más eficiente)
CREATE EXTERNAL TABLE IF NOT EXISTS sales_parquet (
    sale_id     BIGINT,
    customer_id INT,
    amount      DOUBLE
)
PARTITIONED BY (year INT, month INT)  -- Partition columns
STORED AS PARQUET
LOCATION '/warehouse/sales_parquet/'
TBLPROPERTIES ("parquet.compression"="SNAPPY");

-- Agregar partición manualmente o usar MSCK REPAIR
ALTER TABLE sales_parquet ADD PARTITION (year=2026, month=1)
    LOCATION '/warehouse/sales_parquet/year=2026/month=1/';

-- MSCK REPAIR: descubrir particiones automáticamente
MSCK REPAIR TABLE sales_parquet;

-- ── QUERIES HIVE OPTIMIZADAS ──────────────────────────────────────────────
-- Siempre filtrar por partición para aprovechar partition pruning
SELECT customer_id, SUM(amount) AS total
FROM sales_parquet
WHERE year = 2026 AND month BETWEEN 1 AND 3  -- ✅ Usa partición
GROUP BY customer_id;

-- ORC vs Parquet en Hive
-- ORC (Optimized Row Columnar): mejor para Hive, soporta ACID, mejor compresión
-- Parquet: mejor interoperabilidad con Spark, Python, Arrow

Formatos de Archivo en Big Data

La elección del formato de archivo impacta directamente el costo, la velocidad y la flexibilidad de tu plataforma de datos. Este es un conocimiento fundamental que diferencia a los seniors.

📄 CSV / TSV Row-based

El formato más simple. Legible por humanos y cualquier herramienta. Pero extremadamente ineficiente para analytics: no compresión nativa, sin tipos de datos, debe leerse completo para cualquier query.

Usa cuando: Intercambio de datos entre sistemas, archivos pequeños, debugging. Evita: Para storage de producción, analytics a escala.

🔵 Apache Parquet Columnar

El estándar moderno para Data Lakes. Formato columnar que solo lee las columnas necesarias. Compresión excelente (SNAPPY, ZSTD). Compatible con Spark, Pandas, Arrow, BigQuery, Snowflake y casi todo.

# Escribir Parquet con Python
import pandas as pd
df.to_parquet('output.parquet', engine='pyarrow', compression='snappy')

# Leer solo columnas necesarias (columnar advantage)
df = pd.read_parquet('output.parquet', columns=['customer_id', 'amount'])

Usa cuando: Casi siempre en Data Lakes y DWH. Es el default para Spark y dbt.

🟢 Apache Avro Row-based + Schema Evolution

Formato binario row-based con schema evolution robusta. Ideal para event streaming (Kafka) donde el schema puede cambiar. Separa el schema del dato. Integración nativa con Confluent Schema Registry.

// Schema Avro (JSON)
{
  "type": "record",
  "name": "Order",
  "fields": [
    {"name": "order_id", "type": "long"},
    {"name": "amount",   "type": "double"},
    {"name": "status",   "type": "string", "default": "pending"},
    // Nuevo campo con default: schema-compatible!
    {"name": "discount", "type": ["null", "double"], "default": null}
  ]
}

Usa cuando: Mensajes en Kafka, cuando el schema evoluciona frecuentemente, interoperabilidad Java.

🟣 Apache ORC Columnar + ACID

Optimized Row Columnar. Similar a Parquet pero con mejor soporte ACID en el ecosistema Hive. Mejor compresión en algunos casos. El formato preferido para Apache Hive y Hadoop tradicional.

Usa cuando: Ecosistema Hive, necesitas ACID nativo sin Delta Lake.

Comparativa de Formatos

FormatoOrientaciónCompresiónSchema EvolutionPerformance AnalyticsPerformance Streaming
CSVRow❌ No nativo❌ Ninguna🔴 Muy mala🟡 Simple
JSONRow❌ No nativo✅ Flexible🔴 Muy mala🟡 Flexible
AvroRow🟡 Buena✅ Excelente🟡 Media🟢 Excelente
ParquetColumnar🟢 Excelente🟡 Limitada🟢 Excelente🟡 No ideal
ORCColumnar🟢 Excelente🟡 Limitada🟢 Excelente (Hive)🔴 No ideal

Delta Lake

Delta Lake es una capa de storage open source que agrega confiabilidad ACID sobre Parquet en object storage (S3, GCS, ADLS). Es el componente central del patrón Lakehouse.

Funcionalidades Clave de Delta Lake

⚛️

ACID Transactions

Garantías ACID completas sobre object storage. Múltiples writers simultáneos sin corrupción.

Time Travel

Consultar cualquier versión histórica de la tabla. Auditoría completa, rollback a versión anterior.

🔄

Schema Evolution

Agregar columnas sin reescribir toda la tabla. Schema enforcement para calidad de datos.

🔀

MERGE (Upsert)

INSERT + UPDATE + DELETE en una sola operación atómica. Fundamental para SCDs y CDC.

Data Skipping

Statistics por archivo (min, max, null count) que permiten saltar archivos irrelevantes.

🔁

Unified Batch+Stream

El mismo formato para batch y streaming. Elimina la complejidad de Lambda Architecture.

"""
Delta Lake con PySpark
"""
from pyspark.sql import SparkSession
from delta.tables import DeltaTable
from pyspark.sql.functions import *

spark = (SparkSession.builder
    .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension")
    .config("spark.sql.catalog.spark_catalog", "org.apache.spark.sql.delta.catalog.DeltaCatalog")
    .getOrCreate()
)

# ── CREAR DELTA TABLE ──────────────────────────────────────────────────────
df = spark.read.parquet("s3://bucket/raw/orders/")
(df.write.format("delta")
    .mode("overwrite")
    .partitionBy("year", "month")
    .option("overwriteSchema", "true")
    .save("s3://bucket/silver/orders/")
)

# ── TIME TRAVEL ────────────────────────────────────────────────────────────
# Ver historial de la tabla
spark.sql("DESCRIBE HISTORY delta.`s3://bucket/silver/orders/`").show()

# Consultar versión específica
df_v3 = spark.read.format("delta").option("versionAsOf", 3).load("s3://bucket/silver/orders/")

# Consultar por timestamp
df_yesterday = spark.read.format("delta") \
    .option("timestampAsOf", "2026-01-14") \
    .load("s3://bucket/silver/orders/")

# ── MERGE (CDC Pattern) ────────────────────────────────────────────────────
delta_table = DeltaTable.forPath(spark, "s3://bucket/silver/orders/")

# CDC: aplicar cambios incrementales
cdc_df = spark.read.parquet("s3://bucket/cdc/orders/latest/")

(delta_table.alias("target")
    .merge(cdc_df.alias("source"), "target.order_id = source.order_id")
    .whenMatchedUpdate(
        condition="source.op = 'UPDATE'",
        set={"status": "source.status", "updated_at": "source.updated_at"}
    )
    .whenMatchedDelete(condition="source.op = 'DELETE'")
    .whenNotMatchedInsert(
        condition="source.op = 'INSERT'",
        values={"order_id": "source.order_id", "amount": "source.amount", "status": "source.status"}
    )
    .execute()
)

# ── OPTIMIZE & VACUUM ──────────────────────────────────────────────────────
# Compactar archivos pequeños (el "small files problem")
spark.sql("OPTIMIZE delta.`s3://bucket/silver/orders/` ZORDER BY (customer_id)")
# ZORDER: co-localiza datos relacionados → data skipping más efectivo

# Limpiar versiones históricas antiguas (>7 días default)
spark.sql("VACUUM delta.`s3://bucket/silver/orders/` RETAIN 168 HOURS")

Apache Iceberg

Apache Iceberg es el principal competidor de Delta Lake. Iniciado por Netflix, ofrece ACID sobre object storage con un enfoque más abierto y con mejor soporte multi-engine.

Delta Lake vs Apache Iceberg vs Apache Hudi

FeatureDelta LakeApache IcebergApache Hudi
OrigenDatabricksNetflix / ApacheUber / Apache
ACID✅ Completo✅ Completo✅ Completo
Time Travel✅ Versiones✅ Snapshots✅ Timeline
Multi-engine🟡 Spark-first✅ Excelente🟡 Spark-first
Merge-on-Read🟡 Limitado✅ Native✅ Nativo
Streaming✅ Nativo🟡 Limitado✅ Nativo
Cloud DWHDatabricks, AzureSnowflake, AthenaAWS EMR
GovernanceUnity CatalogApache PolarisBásico
Adopción 2026🥇 Líder🥈 Creciendo rápido🥉 AWS-centric
💡 ¿Cuál elegir en 2026?

Delta Lake: Si usas Databricks o Azure Synapse. Apache Iceberg: Si necesitas multi-engine (Spark + Flink + Trino + Snowflake) y máxima neutralidad de vendor. Snowflake e AWS Athena tienen soporte nativo de Iceberg. La industria tiende a converger en Iceberg para long-term open table format.