Saltar al contenido

lección 2

Día 1 -- Diseñar ingesta de sensor de vibración a escala

Fernando te pide diseñar la ingesta de 720 sensores de vibración de alta frecuencia. Evalúas 3 opciones arquitectónicas, decides schema, particionado y retención. Entregas un ADR completo.

⏱ 70 min

## Lunes, 8:30 AM -- El brief de Fernando

Datos de apoyo para hoy: abre `datos/lecturas_vibracion_sample.parquet` (columnas `sample_id, sensor_id, machine_id, timestamp, amplitude, axis`) -- es una muestra real de vibración a 50 Hz de 3 sensores que usarás para estimar volumen, validar el schema v2 y razonar el particionado. Cruza con `datos/maquinas.csv` y `datos/sensores.csv` para mapear cada sensor a su máquina y línea.

Es tu tercer día en SmartFactory. Has pasado los dos primeros leyendo código, explorando Grafana y entendiendo el flujo de datos con Kenji. Hoy empieza el trabajo real. Fernando te cita en su despacho a las 8:30 -- un espacio minimalista con vistas a la planta desde el tercer piso. En la pared hay un diagrama de Gantt físico (sí, en papel) con los hitos del trimestre.

1Fernando: "Buenos días. Siéntate. Tengo un problema y necesito tu
2recomendación para mañana a las 10.
3
4Contexto: los sensores de vibracion actuales miden a 1 Hz -- una
5lectura por segundo. Patricia me dice que para detectar degradación
6de rodamientos con tiempo suficiente necesitamos 5 Hz. Eso multiplica
7por 5 el volumen de vibracion: de 520 ev/s a 2.600 ev/s.
8
9Ademas, quiero anadir 200 sensores nuevos en maquinas que hoy no
10tienen instrumentacion de vibracion. Total: 720 sensores a 5 Hz =
113.600 eventos por segundo SOLO de vibracion.
12
13El Kafka actual aguanta en teoria, pero quiero que PIENSES si es la
14mejor opcion o si hay alternativas. Lo que NO quiero es que implementes
15lo primero que se te ocurra.
16
17Entregable: un documento de 1 pagina con 3 opciones, trade-offs en
185 dimensiones y tu recomendación. Lo revisamos mañana a las 10.
19
20Ah, y baja a planta a hablar con Patricia. Ella sabe que datos
21necesita exactamente del sensor de vibracion. No asumas -- pregunta."

Fernando espera una PROPUESTA, no una pregunta. Este es el nivel senior.

## 9:00 AM -- Reunion con Patricia en planta

Bajas al primer piso y cruzas la puerta de seguridad hacía la planta (casco, gafas, tapones obligatorios). Encuentras a Patricia junto a "La Bestia" -- una fresadora CNC de 5 ejes Mazak Integrex, 4 metros de alto, que mecaniza engranajes planetarios con precisión de 3 micras. Patricia tiene un osciloscopio portatil conectado a un acelerometro y estudia la forma de onda.

1Patricia: "Ah, tu eres el nuevo de datos. Ven, mira esto."
2[Senala la pantalla del osciloscopio]
3
4"Ves está onda? Esto es la vibracion de 'La Bestia' en condiciones
5normales. Frecuencia dominante a 180 Hz -- es la velocidad del husillo.
6Amplitud RMS de 2.1 mm/s. Todo normal.
7
8Ahora mira esto..." [cambia a una grabacion guardada]
9
10"Esto es de hace 3 semanas, cuando el rodamiento del husillo empezó
11a degradarse. Ves como aparece un armonico a 720 Hz? Eso es 4x la
12frecuencia del husillo -- es la frecuencia de pasó de bola del
13rodamiento. Cuando ese armonico supera el 30% de la amplitud del
14fundamental, tenemos 24-48 horas antes del fallo.
15
16Lo que necesito del sensor nuevo:
171. Valor RMS de vibracion (ya lo tenemos, pero a 1 Hz se me escapa el pico)
182. Valor de PICO -- el máximo absoluto dentro de la ventana
193. Frecuencia dominante -- para separar vibracion normal de armonicos
204. Temperatura del punto de medicion -- la degradación genera calor
21
22Y que me lo mande cinco veces por segundo. Ojo, que no te confundas
23con lo que hace el aparato por dentro: el acelerometro muestrea a
24varios kilohercios, que es lo que hace falta para ver un armonico de
25720 Hz. Lo que yo te pido es cada cuanto me manda el resumen de esa
26ventana. Hoy me lo manda una vez por segundo, y en un segundo entero
27el pico se me diluye en la media. Con cinco por segundo veo el
28armonico crecer con tiempo de sobra. Idealmente diez, pero se que es
29mucho dato y los de datos siempre os quejais del volumen."
30[Sonrie]
31
32"Latencia: me da igual si tardo 5 minutos en ver la alerta. Lo
33que NO puedo tolerar es perder datos. Si me pierdo la ventana de
34detección por datos perdidos, la maquina falla sin aviso y tengo
35que explicarle a Fernando por que paramos la linea 3 durante 6 horas
36a 36.000 euros la hora."

Patricia te da requisitos EXACTOS. Un buen senior PREGUNTA antes de disenar.

Una regla que te va a servir cada vez que te den un sensor: para poder ver una señal de X hercios hay que muestrear al menos al doble, 2X. Se llama criterio de Nyquist. Por eso un acelerómetro que tiene que detectar armónicos de rodamiento a 720 Hz muestrea por dentro a varios kilohercios, y por eso su ficha dice que analiza de 10 a 5.000 Hz. Y por eso hay que separar dos números que se parecen y no son lo mismo: a qué ritmo mide el aparato (kilohercios, decisión del fabricante, no la tocas) y a qué ritmo te manda el resultado (5 Hz, decisión tuya, y la que te cuesta el dinero en Kafka). Cuando alguien de planta te diga "necesito más frecuencia", lo primero que hay que aclarar es de cuál de las dos está hablando. Casi siempre es la segunda.

## 10:00 AM -- Reunion con Kenji: contexto técnico

Vuelves a la sala de datos. Kenji te está esperando con un cafe. "Que tal Patricia? Ya te ha enseñado el osciloscopio?" Se rie. "Siempre lo hace con los nuevos. Pero tiene razon -- sabe más de vibraciones que cualquier paper que puedas leer. Ven, te cuento el contexto técnico que necesitas para la propuesta."

1Kenji: "Los sensores nuevos son Siemens MVM-500. Los he mirado ya:
2
3- Soportan MQTT nativo (protocolo IoT estandar, muy ligero)
4- Tambien tienen API REST para configuración y data pull
5- Los actuales publican via un gateway industrial Kepware que
6 convierte OPC-UA a Kafka. Funciona, pero es una caja negra.
7
8Hay basicamente 3 opciones para la ingesta:
9
10Opcion A: Kafka directo via Kepware.
11El gateway actual lee los sensores nuevos y publica a Kafka igual
12que los existentes. Ventaja: no cambias nada en la arquitectura
13downstream. Desventaja: Kepware tiene un límite de 5000 tags y ya
14estamos en 3800. Echa la cuenta bien, que tiene truco: los 520
15sensores de vibracion que ya tenemos publican hoy un solo tag, el
16RMS, y con el schema v2 pasan a cuatro. Eso son 1.560 tags mas sin
17anadir un solo sensor. Y encima los 200 nuevos traen 800. Total
182.360, que nos deja en 6.160. Nos pasamos del limite en 1.160.
19
20Opcion B: MQTT a Bridge a Kafka.
21Los MVM-500 publican a un broker MQTT (Mosquitto o EMQX). Un
22conector Kafka-MQTT hace el bridge. Ventaja: MQTT está diseñado
23para IoT, maneja reconexiones y QoS. Desventaja: nuevo componente
24que mantener, equipo no tiene experiencia.
25
26Opcion C: Edge buffer + batch publish.
27Un agente local en el armario de control de cada linea acumula
28lecturas durante 200 ms y publica el lote comprimido a Kafka. Con
29doce agentes, eso son ~60 mensajes por segundo en vez de 3.600,
30sesenta veces menos, y comprimidos en lote ocupan bastante menos.
31Desventaja: anade 200 ms de latencia, hay que mantener doce agentes
32en armarios de planta, y si uno se cae se pierde lo que tuviera en
33memoria.
34
35Mi opinion? Yo iria por la B, pero no tengo datos para justificarlo.
36Fernando quiere números, no opiniones. Por eso te ha contratado."

Kenji te da el contexto técnico. La decisión es tuya.

## El problema de diseño: marco de evaluación

Antes de ponerte: lo que Fernando te ha pedido tiene nombre y formato conocido. Se llama ADR, Architecture Decision Record, y es el documento de una página con el que un equipo deja constancia de una decisión de arquitectura. Lleva siempre lo mismo: el contexto y las restricciones que obligan a decidir, las opciones que se consideraron de verdad, los criterios con los que se compararon, la decisión tomada y sus consecuencias, incluidas las malas. Se escribe por una razón muy concreta: dentro de dieciocho meses alguien --puede que tú-- va a mirar esta plataforma y va a preguntar "por qué está montado así". Sin ADR, la respuesta es un encogimiento de hombros y un rediseño desde cero. Con ADR, la respuesta es "porque en marzo de 2024 Kepware estaba a 3.800 tags de 5.000, y estas eran las alternativas". Un ADR no sirve para justificar la decisión ante tu jefe: sirve para que el que venga después no repita el análisis.

Tienes toda la información que necesitas. Ahora es tu trabajo sintetizarla en una propuesta estructurada. Como senior, usas un marco de evaluación de 5 dimensiones que te ha servido en todas tus empresas anteriores: rendimiento, fiabilidad, complejidad operacional, coste y evolución futura.

Los números que debes considerar:

  • 720 sensores x 5 Hz = 3.600 eventos/segundo
  • Schema enriquecido con 4 mediciones + metadata = ~320 bytes/mensaje (JSON), ~200 bytes (Avro comprimido)
  • Throughput neto: 3.600 x 320 = 1.15 MB/s en JSON, 0.72 MB/s en Avro
  • Kafka actual: 5 brokers, cada uno soporta ~50 MB/s. Capacidad total: ~250 MB/s. Uso actual: ~12 MB/s
  • Limite Kepware: 5000 tags, uso actual: 3800. Los 520 sensores de vibracion actuales pasan de 1 tag (RMS) a 4 con el schema v2 = +1.560 tags; los 200 nuevos aportan +800. Total +2.360, que deja el sistema en 6.160: se pasa del limite en 1.160
  • Replicación: 3 copias de cada partición (tolera la caída de 2 brokers). TODO lo que calcules de disco va multiplicado por tres
  • Retencion actual: 72h. A 3.600 ev/s x 320 bytes x 72h = ~300 GB de datos de vibracion, que replicados x3 son ~900 GB repartidos entre los 5 brokers: unos 180 GB por broker solo de vibracion
  • Presupuesto de Fernando para infra nueva: 5.000 EUR/mes máximo
  • Timeline: 4 semanas desde aprobacion hasta producción

Pensar como senior: cuando evalúes opciones, nunca uses solo una dimensión. Una solución puede ser la más rápida (rendimiento) pero la más difícil de mantener (complejidad). Otra puede ser la más barata hoy pero la que peor escala mañana. Tu trabajo es encontrar el EQUILIBRIO óptimo para ESTE contexto, no la solución "perfecta" en abstracto.

## Decisiones de schema: backward compatibility

Antes de evaluar opciones de transporte, necesitas definir el schema del nuevo evento. El reto: los consumidores actuales de Spark leen el campo "value" (un float con el RMS). Si cambias el schema sin backward compatibility, rompes el pipeline de alertas que lleva 18 meses funcionando. Kenji te mira: "Lo que sea que hagas, no me rompas el streaming de alertas. Si eso se cae a las 3 AM, me llama el coordinador de planta a MI telefono."

1// Schema v2 propuesto -- backward compatible con v1
2// Campos nuevos tienen default para que consumidores v1 no rompan
3{
4 "sensor_id": "VIB-0047",
5 "machine_id": "GRD-148",
6 "line_id": "LINE-03",
7 "plant_id": "PLANT-VIT",
8 "timestamp": "2024-03-15T08:23:41.847Z",
9 "type": "vibration",
10 "value": 4.72,
11 "unit": "mm/s2",
12 "measurements": {
13 "rms_mm_s": 4.72,
14 "peak_mm_s": 12.8,
15 "dominant_freq_hz": 720,
16 "bearing_temp_c": 67.3
17 },
18 "config": {
19 "sample_rate_hz": 5,
20 "axis": "horizontal",
21 "freq_range": "10-5000"
22 },
23 "quality_flag": "GOOD",
24 "metadata": {
25 "firmware_version": "3.0.1",
26 "battery_pct": 87,
27 "signal_strength_dbm": -42,
28 "calibration_date": "2024-01-15"
29 }
30}

Schema v2: el campo "value" se mantiene (legacy) + nuevo objeto "measurements"

La estrategia de compatibilidad es dual-write: el campo "value" sigue conteniendo el RMS (lo que leen los consumidores v1) y el nuevo objeto "measurements" contiene los 4 campos de Patricia. Durante 30 días, ambos coexisten. Los consumidores se migran gradualmente al nuevo formato. Despues de 30 días, el campo "value" se depreca.

## Decisiones de particionado

El particionado en Kafka determina el paralelismo de consumo. Para sensores industriales hay 3 estrategias viables, cada una con implicaciones diferentes en el procesamiento downstream:

  • Por machine_id: todos los datos de una maquina en la misma particion. Pro: correlación entre sensores de una maquina sin shuffle en Spark. Contra: hot partitions si una maquina tiene 15 sensores (75 ev/s) y otra tiene 3 (15 ev/s).
  • Por line_id: datos de una linea completa juntos. Pro: 12 lineas distribuyen uniformemente en 24 particiones (2 por linea). Contra: Patricia necesita correlación por maquina, no por linea -- requiere shuffle.
  • Por sensor_id: máxima distribución, cada sensor en una particion aleatoria. Pro: distribución perfecta. Contra: correlacionar sensores de la misma maquina requiere shuffle masivo en Spark (costoso a 3600 ev/s).

La decisión depende de cómo se consumen los datos. Patricia necesita correlacionar temperatura y vibración de LA MISMA máquina para detectar degradación. Eso sugiere particionar por machine_id, y con 340 máquinas sobre 24 particiones el reparto sale razonable: las 24 se ocupan y el desbalance es moderado, factor 3:1 entre la más llena y la más vacía. Lo que NO hay que hacer es escribir el hash a mano como machine_id.hashCode() % 24. En Java hashCode() devuelve un int con signo, así que ese resto puede salir negativo, y un índice de partición negativo no es un desbalance: es una IllegalArgumentException que tira el producer. Con los propios identificadores de la planta, "MACH-L03-3".hashCode() vale -2127150239 y su resto entre 24 es -23; de 400 identificadores del estilo GRD-n, CNC-n y MACH-L03-n, 94 dan resto negativo. El particionador por defecto de Kafka usa murmur2 y enmascara el bit de signo precisamente por esto, así que lo correcto es pasarle la key y no tocar nada. Si algún día necesitas tu propio particionador, el resto va sobre el valor absoluto.

Decision crítica: si eliges particionar por line_id (mejor distribución), el pipeline de features de Patricia necesitara un repartition() por machine_id en Spark. A 3.600 ev/s y 320 bytes por mensaje, ese shuffle mueve como mucho ~1,2 MB/s entre executors, que es el stream entero. Es poca cosa, pero es un coste fijo que no existiria con particionado por machine_id. Documenta el trade-off.

## Decisiones de retención: tiered storage

La retención actual de 72 horas en brokers funciona con el volumen actual (~12 MB/s total = ~3 TB en 72h repartidos en 5 brokers). Pero con vibracion a 5 Hz, solo ese topic anade 1.15 MB/s = ~300 GB en 72h. Kenji te comenta: "Fernando quiere minimizar el coste de Kafka sin perder la capacidad de reprocesar si algo falla. Kafka tiene tiered storage desde la versión 3.6 -- primeras N horas en disco local del broker, después se mueve a S3 automaticamente."

Las opciones de retención y su impacto:

  • 24h local + 7 días S3: coste mínimo en brokers (~60 GB/broker para vibracion, contando las 3 copias repartidas entre 5 brokers), recovery window de 7 días. Si Spark falla un fin de semana entero, puedes reprocesar del lunes.
  • 48h local + 7 días S3: cubre un fin de semana parcial en hot storage. Mejor rendimiento de lectura para Spark (disco local vs S3) si hay retraso menor a 2 días.
  • 72h local (sin tiered): actual. Sencillo pero costoso. A 5 Hz necesitas discos más grandes en los brokers o los llenas en días.
  • Solo S3 (Kafka como buffer de 4h): mínimo coste de broker pero peor latencia de lectura para consumidores. No recomendable para streaming de alertas.

Tu recomendación debe considerar que el consumidor de Spark Streaming tiene un SLA de lag máximo de 30 segundos. Si Spark falla, Airflow tiene un DAG de recovery que reprocesa desde el offset almacenado en Kafka. El SLA de recovery es 4 horas. Con tiered storage (24h local + 7d S3) cubres cualquier escenario de fallo razonable sin explotar el disco de los brokers.

Regístrate para guardar tu progreso.