Arquitectura Lakeflow de producción
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_appBronze Raw
Streaming Tables · bytes Avro, headers, offsetsSin pérdida intencionada de eventosSilver
Deserialización Avro · calidad · CDCStreaming Tables / Materialized ViewsGold
Materialized Views · KPIs diarios, semanales y mensualesPower 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
@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
@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
@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 minutosTask 1 · Bronze
Actualizar eventos pendientesTask 2 · Silver
Transformaciones y CDCTask 3 · Gold
Actualizar KPIsNo 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
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.