Lakeflow, lección 15 de 17

Arquitectura Lakeflow de producción

Christian Herrera10 min de lectura orientativa

Objetivo: diseñar una arquitectura Bronze → Silver → Gold que sea incremental, recuperable, observable y fácil de desplegar en varios países.

1. Nuestra arquitectura de referencia

Azure Event Hubs

analytical_ticket · user_profile · tracking_app
Pipeline 1 · Ingestion

Bronze Raw

Streaming Tables · bytes Avro, headers, offsetsSin pérdida intencionada de eventos
Pipeline 2 · Transformación

Silver

Deserialización Avro · calidad · CDCStreaming Tables / Materialized Views
Pipeline 3 · Analytics

Gold

Materialized Views · KPIs diarios, semanales y mensuales

Power BI / Data Products

Unity Catalog gobierna las tablas; los Jobs coordinan la actualización de los pipelines.

Separar ingesta y transformación es una recomendación oficial de Databricks: permite que un error en Silver no detenga la llegada de nuevos datos a Bronze. Databricks on AWS

2. Las decisiones técnicas más importantes

Capa

Tecnología

Motivo

Bronze

Streaming Table

Ingesta incremental y conservación del raw

Silver de eventos

Streaming Table

Deserialización y limpieza append-only

Silver de entidades

AUTO CDC

Mantener el estado de clientes, productos, etc.

Silver con joins cambiantes

Materialized View

Reflejar cambios en las tablas relacionadas

Gold

Materialized View

KPIs y agregaciones actualizables

Orquestación

Lakeflow Jobs

Programación y dependencias entre pipelines

Esta sería mi arquitectura inicial, no una regla universal. Las Streaming Tables, MVs y flows tienen comportamientos diferentes, por lo que cada dataset debe clasificarse según cómo cambian sus datos. Databricks on Google Cloud

3. Código: tres piezas, una arquitectura

Bronze: conservar los eventos originales

python
@dp.table(name="bronze_tickets")
def bronze_tickets():
    return (
        spark.readStream
        .format("kafka")
        # Conexión segura a Event Hubs...
        .load()
        .select(
            "key", "value", "headers",
            "topic", "partition",
            "offset", "timestamp"
        )
    )

Este código esquemático presupone la configuración de conexión de la lección 5, con permisos, secretos y headers habilitados.

Silver: transformar los datos

python
@dp.table(name="silver_tickets")
@dp.expect_or_drop(
    "valid_pharmacy",
    "pharmacy_id IS NOT NULL"
)
def silver_tickets():
    return (
        spark.readStream.table(
            "bronze_deserialized_tickets"
        )
        .select(
            "ticket_id",
            "pharmacy_id",
            "amount",
            "event_time"
        )
    )

Aquí asumimos que ya hemos deserializado Avro y conservamos los importes negativos porque podrían representar devoluciones.

Gold: KPI de ventas diarias

python
@dp.materialized_view(name="gold_daily_sales")
def gold_daily_sales():
    return (
        spark.read.table("silver_tickets")
        .groupBy(
            "pharmacy_id",
            F.to_date("event_time").alias("day")
        )
        .agg(
            F.sum("amount").alias("sales")
        )
    )

La agregación declarativa permite que Lakeflow utilice incremental refresh cuando la consulta y sus fuentes lo admiten. Databricks on Google Cloud

Importante: los nombres de tabla de estos fragmentos son conceptuales. Al separarlos en pipelines, configuraríamos los nombres de catálogo/esquema para que cada consumidor leyera las tablas publicadas por el pipeline anterior.

4. ¿Un pipeline o varios?

Aquí hay una decisión arquitectónica importante.

Opción A. Un único pipeline

Más sencillo de implementar, un único DAG y dependencias automáticas. Adecuado para una PoC o un dominio pequeño.

Opción B. Varios pipelines independientes

Permite distintas frecuencias, recuperaciones y despliegues. Más apropiado para una plataforma con varios dominios, países y consumidores.

Para vuestra plataforma elegiría varios pipelines agrupados por responsabilidad y dominio, evitando tanto un pipeline gigante como decenas de pipelines innecesariamente pequeños.

Una separación física no elimina la necesidad de orquestar las dependencias entre pipelines. Para eso utilizaríamos Lakeflow Jobs.

5. Ejemplo: orquestación en producción

Job: RS Data Platform

Triggered cada 15 minutos

Task 1 · Bronze

Actualizar eventos pendientes

Task 2 · Silver

Transformaciones y CDC

Task 3 · Gold

Actualizar KPIs

No siempre haría esperar Bronze a Gold: si las transformaciones fallan frecuentemente o tienen un SLA diferente, desacoplaría también su programación.

6. Cinco reglas que aplicaría en producción

  • Nunca perder el raw: conservar payload, headers y metadatos Kafka en Bronze.

  • Reprocesar desde Delta: reconstruir Silver desde Bronze, no desde Event Hubs si el histórico ya ha expirado.

  • No confundir eventos con entidades: append-only para eventos; AUTO CDC cuando haya cambios de estado identificables.

  • Diseñar Gold para correcciones: los KPIs históricos deben reflejar cambios anteriores, no solo nuevas inserciones.

  • Medir cada capa: freshness, errores, calidad, throughput y costes.

El cuarto punto nos lleva directamente a la lección 16: si mañana se corrige un ticket de agosto, ¿cómo actualizamos únicamente los KPIs afectados?

7. Mini ejercicio de arquitectura

Tu pipeline Silver falla porque llega una versión Avro que todavía no soportamos.

Mientras tanto, siguen llegando tickets a Event Hubs.

¿Qué arquitectura minimiza el riesgo de interrumpir la ingesta?

¡Correcto!

Bronze continúa ingiriendo mientras corregimos Silver. Después podemos reprocesar desde el histórico Delta conservado.

Qué debes recordar: no existe un único tipo de tabla o pipeline ideal para todas las capas. La arquitectura correcta depende de cómo cambian los datos, del SLA, de los requisitos de recuperación y de cómo consumen la información los equipos de negocio.

Progreso del curso

15 / 17

Solo quedan dos lecciones: CDC vs CDF e incremental refresh histórico; y la comparación final con dbt.

Una idea más en tu cuaderno.

Marca esta lección cuando hayas terminado de repasarla.

Material importado del curso original. Simulaciones conservadas como ejemplos estáticos; para sus controles interactivos, consulta el original.