lección 2
Día 1 -- Architecture Review: diseñar streaming
Evalúas 4 opciones de streaming, escribes un ADR completo con trade-offs y lo defiendes ante Clara en el Architecture Review Board.
⏱ 45 min
### Martes, 9:15 AM -- La pizarra de Alberto
Alberto te lleva a la sala Turing. La pizarra está llena de diagramas a medio borrar de la sesión anterior. Coge un rotulador azul y dibuja el pipeline actual: un DAG de Airflow ("txn_daily_load") que a las 4:00 AM extrae las transacciones del día anterior desde el topic de Kafka hacía S3 raw, las transforma con PySpark en EMR (limpieza + enriquecimiento + deduplicación) y las carga en Redshift gold. Latencia end-to-end: entre 4 y 28 horas dependiendo de si el job falla y hay que relanzarlo manualmente.
Alberto subraya dos números en rojo: "<5 min" y "<15 min". "El negocio necesita dos cosas", dice mientras golpea la pizarra. "Primera: fraude en menos de 5 minutos. El modelo de Miguel necesita features frescas -- si las features tienen más de 5 minutos de antigüedad, la precisión baja de 92% a 67%. Eso son 340 fraudes no detectados al mes, 2.1 millones de euros de pérdidas. Segunda: alertas regulatorias en menos de 15 minutos. El Banco de España nos exige notificación inmediata de transacciones sospechosas por encima de 10.000 euros. Inmediata significa menos de 15 minutos, no al día siguiente."
1Alberto Reyes (pizarra, rotulador rojo):2"No me traigas la solución. Tráeme 3 opciones con trade-offs3claros, coste de cada una, y tu recomendación justificada. Si no4puedes defender tu decisión ante Clara en 5 minutos, no está lista.56El ADR debe estar escrito ANTES del Architecture Review del jueves.7Clara lo va a leer. Si tiene preguntas que no puedes responder,8te manda de vuelta. Y el jueves es el jueves -- no hay segunda9oportunidad está semana."
Alberto establece las reglas del ADR
### Evaluación de opciones
Te sientas en tu escritorio con un café doble y abres un documento en blanco. Necesitas evaluar las opciones viables para consumir del topic transactions.completed de Kafka MSK y reducir la latencia de horas a minutos. Después de investigar 2 horas, identificas 4 candidatos serios:
- 01.Spark Structured Streaming (EMR): Aprovechar la infraestructura existente de Spark. Micro-batch cada 30s-1min. Soporta watermarks para late data, aggregations con ventanas, y exactly-once con checkpoints en S3. El equipo ya conoce PySpark.
- 02.Kafka Connect + S3 Sink: Conector managed que escribe directamente de Kafka a S3. Simple de configurar, bajo mantenimiento. Pero sin transformación inline -- necesitaría un pasó adicional de procesamiento (Lambda o segundo job).
- 03.Consumer Group nativo (Python con confluent-kafka): Escribir un consumer con la librería de Confluent. Máximo control, mínima latencia (<10s). Pero máximo mantenimiento: gestión manual de offsets, errores, escalado, rebalanceo de particiones.
- 04.Amazon Kinesis Data Analytics (Flink managed): Servicio 100% managed de AWS para stream processing. Cero operación, auto-scaling. Pero coste alto, lock-in fuerte con AWS, y el equipo no conoce Flink SQL.
Analizas cada opción contra 5 criterios que Alberto siempre usa: latencia alcanzable, complejidad operativa, coste mensual estimado, integración con el stack existente, y escalabilidad a 10x volumen actual (preparación para Black Friday y campañas de Navidad).
1# Evaluación cuantitativa de las 4 opciones2# Criterios ponderados según prioridades de NeoBank34opciones = {5 "Spark Structured Streaming": {6 "latencia_seg": 45, # Micro-batch cada 30s + processing7 "complejidad_ops": 3, # Media (ya tenemos EMR)8 "coste_mensual_eur": 800, # Cluster EMR siempre encendido9 "integración": 5, # Perfecto: ya usamos PySpark10 "escalabilidad_10x": 4, # Auto-scaling de executors11 "exactly_once": True, # Checkpoints en S312 "equipo_conoce": True, # 8 jobs batch existentes13 },14 "Kafka Connect S3 Sink": {15 "latencia_seg": 180, # flush.size + rotate.interval16 "complejidad_ops": 2, # Baja (managed connector)17 "coste_mensual_eur": 400, # Solo connector + S318 "integración": 3, # Necesita pasó adicional19 "escalabilidad_10x": 3, # Limitado por flush config20 "exactly_once": False, # At-least-once nativo21 "equipo_conoce": False, # Nadie ha usado Connect22 },23 "Consumer Python nativo": {24 "latencia_seg": 8, # Procesamiento inmediato25 "complejidad_ops": 5, # Alta (todo manual)26 "coste_mensual_eur": 300, # ECS Fargate27 "integración": 4, # Python, compatible28 "escalabilidad_10x": 2, # Manual, frágil29 "exactly_once": False, # Requiere implementación manual30 "equipo_conoce": True, # Python sí, pero no a este nivel31 },32 "Kinesis Data Analytics": {33 "latencia_seg": 45, # Similar a Spark micro-batch34 "complejidad_ops": 1, # Zero ops (managed)35 "coste_mensual_eur": 1500, # KPU pricing es caro36 "integración": 2, # Flink SQL != PySpark37 "escalabilidad_10x": 5, # Auto-scaling nativo38 "exactly_once": True, # Built-in39 "equipo_conoce": False, # Nadie conoce Flink40 },41}4243# Pesos de cada criterio (según prioridades de Alberto/Clara)44pesos = {45 "latencia": 0.25, # SLA es crítico46 "complejidad": 0.20, # Menos ops = más tiempo para features47 "coste": 0.15, # Presupuesto limitado pero no bloqueante48 "integración": 0.25, # Reutilizar stack reduce riesgo49 "escalabilidad": 0.15, # Importante pero a medio plazo50}5152print("╔══════════════════════════════════════════════════════════════╗")53print("║ EVALUACIÓN DE OPCIONES -- STREAMING NEOBANK ║")54print("╠══════════════════════════════════════════════════════════════╣")55for nombre, datos in opciones.items():56 cumple_sla = datos["latencia_seg"] < 300 # 5 min = 300 seg57 print(f"║ {nombre:35s} ║")58 print(f"║ Latencia: {datos['latencia_seg']:>3}s | Coste: {datos['coste_mensual_eur']:>4} EUR/mes ║")59 print(f"║ Exactly-once: {'Sí' if datos['exactly_once'] else 'No':2s} | SLA: {'✓ CUMPLE' if cumple_sla else '✗ FALLA'} ║")60 print(f"║ Equipo conoce: {'Sí' if datos['equipo_conoce'] else 'No'} ║")61 print("╠══════════════════════════════════════════════════════════════╣")62print("║ RECOMENDACIÓN: Spark Structured Streaming ║")63print("╚══════════════════════════════════════════════════════════════╝")
Evaluación cuantitativa de las 4 opciones de streaming
### El ADR -- Architecture Decision Record
Con la evaluación clara, escribes el ADR. Alberto tiene un template estándar que todo el equipo usa -- basado en el formato de Michael Nygard pero adaptado a NeoBank con una sección de "Impacto regulatorio" que no existe en ADRs estándar.
1# ADR-007: Migración a Near-Real-Time para Pipeline de Transacciones23## Estado4Propuesto (pendiente aprobación ARB 2024-03-14)56## Contexto7El pipeline batch actual (Airflow DAG "txn_daily_load") procesa8transacciones con latencia de 4-28h. Los SLAs de negocio exigen:9- Modelo de fraude: features con frescura <5 min (impacto: 2.1M EUR/mes)10- Alertas regulatorias BdE: notificación de txns >10K EUR en <15 min11- Feature store: alimentar 5 features para scoring de fraude1213Topic Kafka: transactions.completed14Volumen actual: ~4.5M eventos/día (~52 eventos/seg, picos 200/s)15Formato: Avro con Schema Registry (schema v3.2)16Retención Kafka: 7 días1718## Opciones evaluadas1920La comparación de las 4 opciones frente a los criterios clave está21en la tabla siguiente (la columna elegida aparece resaltada).
ADR-007 (parte 1): estado, contexto y opciones sobre la mesa
1### Opciones descartadas y justificación23**Kafka Connect S3 Sink:** Cumple SLA de latencia marginalmente (1-3 min)4pero no permite transformación inline. Necesitaríamos un segundo pasó5(Lambda o Spark batch) para enriquecer y calcular features, lo que añade6complejidad y latencia. Descartado por arquitectura fragmentada.78**Consumer Python nativo:** Latencia mínima pero escalabilidad manual y9fragilidad operativa. Con 4.5M eventos/día y picos de 200/s, un solo10consumer no basta. Gestionar consumer groups, rebalanceo y exactly-once11en Python es un proyecto en sí mismo. Descartado por riesgo operativo.1213**Kinesis Data Analytics:** Técnicamente viable pero 1.500 EUR/mes para14un volumen que Spark maneja por 800 EUR. Además, el equipo no conoce15Flink SQL y la migración de lógica PySpark a Flink tiene coste oculto16significativo. Descartado por coste + lock-in + curva de aprendizaje.1718## Decisión19**Spark Structured Streaming en EMR** con micro-batch de 30 segundos.2021## Justificación221. Ya tenemos EMR y 8 jobs PySpark batch -- el equipo conoce la API232. Exactly-once garantizado con checkpoints en S3 (crítico en banca)243. Watermarks nativos para manejar late data (txns que llegan tarde)254. Escala horizontalmente añadiendo executors (auto-scaling configurado)265. Micro-batch de 30s cumple SLA de 5 min con margen de 6x276. Reutiliza schemas Avro + lógica de transformación existente2829## Impacto regulatorio30- Mejora cumplimiento de notificación al BdE (de 24h a <1 min)31- Datos financieros permanecen encriptados en tránsito (TLS 1.3)32- Checkpoints en S3 proporcionan audit trail de procesamiento33- Sara (DPO) válida que no hay impacto en retención de datos personales3435## Consecuencias36- [+] Latencia baja a ~45s (cumple ambos SLAs con margen)37- [+] Features de fraude frescas -> modelo recupera 92% precisión38- [-] Cluster EMR siempre encendido (~800 EUR/mes adicionales)39- [-] Equipo debe dominar Structured Streaming (formación 1-2 semanas)40- [-] Necesitamos definir estrategia de checkpoint y recovery41- [~] Pipeline batch se mantiene como fallback durante 2 sprints4243## Métricas de éxito44- Latencia p95 < 60 segundos (medida en Datadog)45- Zero data loss durante 30 días consecutivos46- Consumer lag promedio < 1.000 eventos47- Features de fraude con freshness < 2 minutos4849## Autor y fecha50- Autor: [Data Engineer]51- Fecha: 2024-03-1252- Revisores: Alberto Reyes, Paula García
ADR-007 (parte 2): opciones descartadas, decisión final y métricas de éxito
Un ADR (Architecture Decision Record) no es burocracia -- es la memoria del equipo. Dentro de 6 meses, cuando alguien pregunte "¿por qué usamos Spark y no Kinesis?", el ADR responde sin necesidad de reuniones arqueológicas. Alberto dice: "Si la decisión cuesta más de 2 días revertir, merece un ADR. Si cuesta más de 2 semanas, merece un ADR Y una prueba de concepto."
### El Architecture Review -- defendiendo ante Clara
Jueves 10:00 AM. Sala Grace Hopper. Clara Mendoza preside. Están Alberto, Sara, Miguel, Paula y tú. Clara tiene el ADR impreso con anotaciones en rojo. "Tienes 10 minutos para presentar y 5 para preguntas. Empieza."
Presentas: contexto, opciones, decisión, justificación. Clara interrumpe dos veces:
1Clara Mendoza (ARB, minuto 4):2"Pregunta 1: Si el cluster EMR se cae a las 3AM, ¿cuál es el3Recovery Time Objective? ¿Cuántos minutos perdemos?"45Tu respuesta:6"Los checkpoints en S3 guardan el estado cada micro-batch (30s).7Si el cluster cae, EMR auto-restart lo levanta en ~3 minutos.8El job retoma desde el último checkpoint -- RTO efectivo de93-5 minutos. Zero data loss porque Kafka retiene 7 días."1011Clara Mendoza (minuto 7):12"Pregunta 2: Black Friday. El año pasado tuvimos 5x el volumen13normal durante 72 horas. ¿Qué pasa con tu pipeline?"1415Tu respuesta:16"EMR tiene auto-scaling configurado en Terraform. Puede pasar17de 4 a 12 executors en 4 minutos basándose en consumer lag.18He validado con los números: a 5x volumen (260 eventos/seg),19con 8 executors el micro-batch completa en 22 segundos.20Margen suficiente dentro del trigger de 30 segundos."2122Clara (asiente):23"Aprobado. Siguiente tema."
Architecture Review: las preguntas de Clara y tus respuestas preparadas
Cuando presentes un ADR ante un VP o arquitecto senior, prepara respuestas para las "preguntas asesinas": ¿Qué pasa si se cae? ¿Qué pasa a 10x escala? ¿Cuál es el plan B? ¿Cuánto cuesta si nos equivocamos? Si no puedes responder alguna, di "no lo he evaluado, lo investigo y actualizo el ADR mañana". NUNCA inventes una respuesta.
### Los imprevistos del día
Mientras preparas el ADR (martes por la tarde), recibes dos interrupciones que son completamente normales en un equipo real:
1# Slack DM de Miguel Ortiz -- 14:322Miguel Ortiz:3"Ey, he visto que estás montando el streaming. Necesito que4incluyas el cálculo de features en la misma pipeline --5txn_count_1h, avg_amount_1h y ratio vs histórico. Si las6calculas en streaming me ahorras una consulta a Redis que7tarda 200ms por predicción. Son 52 predicciones/segundo,8200ms cada una... haz la cuenta."910Tú:11"Entendido. Lo tengo en el plan como tarea separada del día 3.12¿Puedes pasarme la spec exacta de las 5 features que necesitas?13Nombres, ventanas temporales, y cómo las consume tu modelo."1415Miguel Ortiz:16"Te mando el doc ahora. Gracias por no decirme 'ya veremos' 👍"
Interrupción de Miguel -- legítima pero hay que priorizarla
1# Email de Sara Vidal -- 16:02 (con copia a legal@neobank.es)2Asunto: URGENTE - Solicitud de supresión RGPD - acc_000284733---4Equipo de datos,56El cliente Jenaro Portero Llorente (acc_00028473) ejerció su derecho7de supresión según el artículo 17 del RGPD el pasado 22 de8febrero de 2024. El plazo legal es de 30 días naturales.910Fecha límite: 23 de marzo de 2024.11Hoy es 6 de marzo. Quedan 18 días naturales (12 laborables).1213Necesito confirmación ESCRITA de que el equipo de datos puede14completar la supresión/anonimización irreversible en todos los15sistemas antes de la fecha límite.1617Por favor, agendad una reunión conmigo mañana a primera hora18para evaluar el alcance.1920Un saludo,21Sara Vidal22DPO - NeoBank23---
Email de Sara -- deadline regulatorio no negociable
En un equipo real, SIEMPRE hay interrupciones. Un día nunca es "una sola tarea". La habilidad no es evitar las interrupciones sino gestionarlas: registrar la petición, confirmar que la has recibido, dar un timeline realista, y seguir con tu prioridad actual. Miguel no es molesto -- es un compañero con una necesidad legítima. Sara no es un obstáculo -- es la persona que protege a la empresa de multas millonarias.
## ejercicios
Evaluar opciones de streaming con scoring
Implementa un sistema de scoring ponderado que evalúe las 4 opciones de streaming según los criterios de NeoBank y genere una recomendación justificada.
Generador de ADR estructurado
Implementa una función que genera un ADR completo como estructura de datos validable, con todos los campos obligatorios que exige el template de NeoBank.
Prototipo Spark Structured Streaming
Completa el job de Spark Streaming que consume del topic transactions.completed, filtra transacciones >10.000 EUR para alertas regulatorias y las escribe a S3 gold particionadas.
Regístrate para guardar tu progreso.
## comentarios
Reporta erratas, ayuda a otros o comparte tu opinión. Sé constructivo.
Inicia sesión para comentar y responder.
cargando comentarios...