Skip to content
SP StackPractices
intermediate Por StackPractices

Data Lake vs Data Warehouse — Guía de Arquitectura

Guía práctica de arquitectura Data Lake: almacenamiento estructurado vs no estructurado, conceptos de lakehouse, patrones ETL vs ELT y cuándo elegir un lake sobre un warehouse.

Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.

Overview

Un Data Lake es un repositorio de almacenamiento centralizado que contiene datos estructurados, semi-estructurados y no estructurados a cualquier escala. A diferencia de un Data Warehouse, que almacena datos procesados con schema-on-write en tablas rígidas, un Data Lake almacena datos crudos en su formato nativo con schema aplicado en lectura (schema-on-read). Esta flexibilidad lo hace ideal para machine learning, análisis exploratorio y almacenar datos cuya estructura aún no se conoce. Sin embargo, sin gobernanza, los lakes pueden convertirse en “data swamps” — desorganizados, no buscables y poco confiables.

Cuándo Usar un Data Lake

  • Necesitas almacenar diversos tipos de datos: JSON, CSV, Parquet, imágenes, videos, logs
  • Las cargas de trabajo de machine learning requieren datos crudos sin procesar
  • El volumen de datos excede lo que las bases de datos tradicionales pueden manejar rentablemente
  • Quieres diferir el diseño de schema hasta que los datos se consuman
  • Los datos históricos deben retenerse barato para análisis futuro

Data Lake vs Data Warehouse

DimensiónData LakeData Warehouse
Tipos de datosTodos (estructurados, semi, no estructurados)Solo estructurados
SchemaSchema-on-readSchema-on-write
UsuariosCientíficos de datos, ingenieros ML, analistasAnalistas de negocio, herramientas BI
Rendimiento de consultaVariable, optimizado para batchRápido, optimizado para OLAP
CostoAlmacenamiento bajo, cómputo altoAlmacenamiento alto, cómputo optimizado
Calidad de datosCrudos, pueden no estar validadosCurados, validados, confiables
EscalaPetabyte+Terabyte a Petabyte

Capas de Arquitectura

Zona Raw (Bronze)
    ├── Datos sin procesar de fuentes
    ├── Retenidos en formato nativo
    └── Almacenamiento barato, largo plazo

Zona Limpia (Silver)
    ├── Datos deduplicados y validados
    ├── Transformaciones básicas aplicadas
    └── Schemas tipados forzados

Zona Curada (Gold)
    ├── Agregados listos para negocio
    ├── Optimizados para rendimiento de consulta
    └── Usados por herramientas BI y aplicaciones

ETL vs ELT

PatrónFlujoMejor Para
ETLExtract → Transform → LoadData warehouses, requerimientos estrictos de schema
ELTExtract → Load → TransformData lakes, flexibilidad de schema-on-read
# Patrón ELT — carga cruda, transforma bajo demanda
import pandas as pd
from pyspark.sql import SparkSession

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

# Extract: Leer logs JSON crudos desde S3
raw_df = spark.read.json("s3://datalake/raw/events/2024/01/")

# Load: Almacenar como Parquet en la zona Silver
raw_df.write.parquet("s3://datalake/silver/events/", mode="overwrite")

# Transform: Aplicar schema y agregaciones bajo lectura
cleaned_df = spark.read.parquet("s3://datalake/silver/events/")
cleaned_df.createOrReplaceTempView("events")

daily_metrics = spark.sql("""
    SELECT 
        DATE(timestamp) as date,
        event_type,
        COUNT(*) as event_count,
        COUNT(DISTINCT user_id) as unique_users
    FROM events
    WHERE timestamp >= '2024-01-01'
    GROUP BY DATE(timestamp), event_type
""")

daily_metrics.write.parquet("s3://datalake/gold/daily_metrics/")

Formatos de Almacenamiento

FormatoTipoCaso de Uso
CSVTextoIntercambio, legible por humanos
JSONSemi-estructuradoAPIs, datos anidados
ParquetColumnarConsultas analíticas, compresión
AvroBasado en filasStreaming, evolución de schema
ORCColumnarCargas de trabajo Hive/Spark
Delta LakeCapaTransacciones ACID sobre lakes

Ejemplo de Delta Lake

from delta import configure_spark_with_delta_pip
from pyspark.sql import SparkSession

builder = SparkSession.builder.appName("DeltaLakeExample") \
    .config("spark.sql.extensions", "io.delta.sql.DeltaSparkSessionExtension")
spark = configure_spark_with_delta_pip(builder).getOrCreate()

# Escribir con garantías ACID
df.write.format("delta").mode("overwrite").save("/datalake/silver/orders")

# Time travel — consultar a partir de una versión específica
spark.read.format("delta").option("versionAsOf", 5).load("/datalake/silver/orders")

# Evolución de schema
df_with_new_column.write.format("delta") \
    .mode("append") \
    .option("mergeSchema", "true") \
    .save("/datalake/silver/orders")

Errores Comunes

  • El data swamp — volcar todo sin catalogar, gobernar o políticas de retención
  • Sin estrategia de particionamiento — consultar lakes sin particionar es dolorosamente lento; particionar por fecha y/o región
  • Usar lakes para OLTP — los lakes son para análisis, no cargas transaccionales
  • Ignorar gobernanza de datos — sin catálogos de metadata y controles de acceso, los lakes se vuelven inusables
  • Problema de archivos pequeños — escribir miles de archivos diminutos mata el rendimiento de consulta; compactar regularmente

FAQ

Puedo consultar un Data Lake con SQL? Sí. Motores de consulta como Athena, Presto/Trino, Dremio y Spark SQL proveen interfaces SQL sobre almacenamiento de lakes.

Es un Data Lake reemplazo de un Data Warehouse? No exactamente. Muchas organizaciones usan ambos: lakes para datos crudos/ML, warehouses para datos curados de BI. Las arquitecturas Lakehouse (Delta Lake, Iceberg) difuminan esta línea.

Cómo evito que mi lake se convierta en un swamp? Implementa: (1) un catálogo de datos para descubrimiento, (2) políticas de retención y archivado, (3) chequeos de calidad en ingesta, (4) propiedad clara por dataset.