Procesamiento de secuencias
Qué es el procesamiento de streaming
El procesamiento de streaming es una respuesta continua a secuencias infinitas de eventos (registro de transacciones, clics, pagos, telemetría), con un retraso mínimo y una garantía de que los estados son correctos. A diferencia de batch, donde «tomamos todo lo acumulado durante el período», el flujo procesa los datos a medida que se reciben, mantiene el estado y toma en cuenta el tiempo del evento.
Conceptos clave
Evento (event) es un hecho inmutable con 'event _ time' y 'event _ id' único.
Tiempo del evento (tiempo de evento) vs tiempo del tratamiento (tiempo de proceso) - el primero viene de la fuente, el segundo - cuando el operador vio realmente el acontecimiento.
- Tumbling (no superposición), Hopping/Sliding (superposición), Session (roturas por inactividad).
- Marcas de agua (watermarks) es la estimación de que «los eventos hasta el momento T ya han llegado», lo que permite cerrar ventanas y limitar la espera de datos atrasados.
- Datos atrasados (lateness): los eventos con 'event _ time' son menores que el watermark actual; a menudo se aplican reglas de preprocesamiento.
- Estado (state): tablas/almacenes de operadores locales (keyed state) para agregados, join's, deduplicación.
- Backpressure: presión cuando se excede la capacidad de descarga; controlado por protocolo y buffers.
las bases Arquitectónicas
1. Fuente (source): corredor de eventos (Kafka/NATS/Pulsar), CDC de la DB, colas, archivos/recopiladores de registros.
2. Motor de flujo: calcula ventanas, agregados, joys, patrones (CEP), controla el estado y checkpoint 'ami.
3. Receptor (sink): OLTP/OLAP DB, motor de búsqueda, caché, topics, repositorios para escaparates/informes.
4. Registro de esquemas: control de la evolución de payload y compatibilidad.
5. Observabilidad: métricas, treysing, logs, dashboards y marcas de agua.
Semántica del tiempo y orden
Siempre prefiera el tiempo de evento: es el único invariante en retrasos e interrupciones.
Los eventos pueden llegar fuera de orden; el orden está garantizado sólo dentro de la clave de lote.
- cerrar las ventanas y emitir los resultados;
- limitar «cuánto esperamos» eventos atrasados ('allowed _ lateness').
- Para eventos atrasados, utilice retractions/upserts: recuento de agregados y eventos correctivos.
Estado y confiabilidad
Estado clave: los datos de los agregados (sumas, contadores, estructuras para el dedup) se distribuyen en llaves.
Checkpoint/Savepoint: instantáneas periódicas de estado para recuperación; savepoint: instantánea administrada para migraciones de versiones de código.
- transaccional «leído-procesado-escrito» (commit sink + posición de lectura);
- sinks idempotentes (upsert/merge) + tablas de dedup;
- versionando los agregados (optimistic concurrency).
Ventanas, agregaciones, join's
Ventanas:- Tumbling: informes periódicos simples (minutos, horas).
- Hopping/Sliding: métricas «deslizantes» (5 min en incrementos de 1 min).
- Sesión: natural para sesiones personalizadas y antifraude.
- Aggregations: sum/count/avg/approx-distinct (HyperLogLog), percentiles (TDigest/CKMS).
- Stream-Stream join: requiere buffering de ambos lados en clave y tiempo, respeta 'allowed _ skew'.
- Stream-Table join (KTable): adjuntar un directorio o estado actual (por ejemplo, «límites de usuario activos»).
Trabajar con datos atrasados y duplicados
Deduplicación: por 'event _ id' o '(producer_id, sequence)'; almacene las claves «visibles» con TTL ≥ la ventana de repetición.
Eventos Late: permite el refinado de la ventana durante 'X' después del cierre (retractions/upserts).
Duplicados falsos: ajusta los agregados de forma idempotente y fija el «ALREADY_APPLIED» en los logs.
Escalamiento y rendimiento
Charding por clave: proporciona paralelismo; cuidado con las llaves «calientes».
Backpressure: limite el paralelismo, use batches y compresión cuando publique.
Marcas de agua: no poner demasiado agresivo - watermarks rígidos reducen la espera, pero aumentan la proporción de actualizaciones late.
Estado: seleccione el formato (RocksDB/state store/en memoria) teniendo en cuenta el tamaño y los patrones de acceso; limpie el TTL.
Escala automática: por la laguna, CPU, tamaño del estado, tiempo de GC.
Fiabilidad y reinicio
Un dink idempotente o commit transaccional con fijación offset es la base de la corrección.
Se permite volver a procesar después del reinicio; el efecto debe permanecer «exactamente una vez».
DLQ/parking lot: enviar los registros problemáticos a un flujo separado con las causas; asegúrese de volver a trabajar.
Observabilidad (qué medir)
Log según las fuentes (según el tiempo y según la comunicación).
Watermark/current event time y proporción de eventos late.
Throughput/latency operadores, p95/p99 end-to-end.
Tamaño del estado/rocksdb I/O, frecuencia checkpoint 's/duración.
Tasa DLQ, porcentaje de deduplicaciones/retraídas.
CPU/GC/heap, tiempo de pausa.
Seguridad y cumplimiento
Clasificación de datos: marcar PII/PCI en circuitos, almacenar mínimo, cifrar state y snapshots.
Control de acceso: ACL individuales en los topics/tablas de estado y en los sinks.
Retenciones: compatibles con los requisitos legales (RGPD/derecho al olvido).
Auditoría: lógica 'event _ id', 'trace _ id', resultado: 'APPLIED/ALEADY _ APPLIED/RETRIED'.
Patrones de implementación
1. Los CDC → la normalización de los eventos de dominio →: no transmitan cambios crudos en la DB, mapee a hechos empresariales comprensibles.
2. Outbox en los productores: el hecho de la transacción + evento - en una transacción de BD.
3. Core vs Enriched: payload mínimo en flujo crítico, enriquecimiento - asíncrono.
4. Resplay-friendly: las proyecciones/vitrinas deben reescribirse desde el registro.
5. Idempotency by design: operation/event key, esquemas upsert, versiones de agregados.
Pruebas
Unit/Property-based: invariantes de agregados y transformaciones.
Pruebas de Stream: flujo de eventos fijo con salida de orden y duplicados → comprobación de ventanas y dedo.
Ventanas de oro: ventanas/agregados de referencia y ajustes tardíos válidos.
Fault-injection: una caída entre «registró el efecto» y «commitió el offset».
Pruebas de respuesta: Reconfiguración del escaparate desde el inicio del registro = estado actual.
Costo y optimización
Ventanas y watermark afectan a la latencia/recursos: cuanto más larga es la ventana y más 'allowed _ lateness', más grande es el estado.
Codecs y compresión: equilibra la CPU/red.
Batching en la salida: menos llamadas de red y transacciones.
Filtrado temprano («pushdown»): descargue el exceso lo más cerca posible de la fuente.
Antipattern
Un atadura en el tiempo de procesamiento donde se necesita el tiempo de evento → un análisis incorrecto.
La falta de idempotencia en sink → efectos dobles en restarts.
«Mega-claves» globales: una sección caliente rompe el paralelismo.
Los CDC crudos como eventos públicos: filtración de esquemas de DB, fragilidad en la evolución.
No DLQ: los mensajes «venenosos» bloquean todo el transportador.
Latencia rígida fija en lugar de watermark: o espera eterna o pérdida de datos.
Ejemplos de dominio
Pagos/finanzas
Flujo 'payment.', ventanas antifraude (session + CEP), dedoup por 'operation _ id'.
Exactly-once efecto cuando se divide en ledger contable (upsert + versión).
Marketing/Publicidad
Ventana deslizante CTR/conversiones, clic Join e impresiones con tolerancia '± Δ t', agregaciones para bidding.
iGaming/servicios en línea
Balance/límites de tiempo real, misiones/acolchados (ventana de sesión), patrones antifraude y alertas.
Mini plantillas (pseudocódigo)
Ventana con marcas de agua y actualizaciones late
pseudo stream
.withEventTime(tsExtractor)
.withWatermark(maxAllowedLag=2m)
.window(TUMBLING, size=1m, allowedLateness=30s)
.keyBy(user_id)
.aggregate(sum, retractions=enable)
.sink (upsert_table )//idempotent upsert by (user_id, window_start)
Sink transaccional con confirmación offset
pseudo begin tx upsert target_table using event, key=(k)
update consumer_offsets set pos=:pos where consumer=:c commit
Lista de comprobación de producción
- Se definen el tiempo de evento y la estrategia de watermark; las ventanas y 'allowed _ lateness' están seleccionadas.
- Dink idempotente o commit transaccional con offset.
- El registro de esquemas y los modos de compatibilidad están habilitados; evolución aditiva.
- Métricas: mag, watermark, p95/p99, DLQ, tamaño state, duración checkpoint.
- Pruebas: fuera de orden, duplicados, reinicios, replay.
- Políticas de PII/retención para state y snapshots.
- Plan de escala y estrategia de backpressure.
- Documentación sobre contratos de ventanas y ajustes (late updates).
FAQ
¿El tiempo de evento es obligatorio?
Si la corrección de las métricas y la consistencia son importantes, - sí. El tiempo de procesamiento es adecuado para cuentas técnicas/monitoreo, pero distorsiona la analítica.
¿Es necesario un exactly-once?
Punto: para efectos críticos. Más a menudo es suficiente en-least-once + dink idempotente.
¿Cómo elegir las ventanas?
Opta por el SLA empresarial: «en los últimos 5 minutos» → hopping, «sesiones de usuario» → sesión, «informes de minutos» → tumbling.
¿Qué debo hacer con los datos tardíos?
Permitir «allowed _ lateness» restringido y emitir ajustes (upsert/retract). El escaparate del cliente debe ser capaz de actualizar.
El flujo de procesamiento no es sólo un retraso bajo, sino también una disciplina de tiempo, estado y contratos. La elección correcta del momento del evento, las ventanas y las marcas de agua, además de los efectos idempotentes, la observabilidad y las pruebas hacen que el transportador sea confiable, reproducible y económico, y le dan al negocio soluciones «aquí y ahora» en lugar de «a través de la noche».