(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo hacer deduplicación en Real-Time Analytics: paso a paso

João Barros 05 de August de 2026 4 min de lectura

Este tutorial muestra cómo implementar deduplicación de eventos en Real-Time Analytics para evitar recuentos duplicados cuando múltiples eventos idénticos llegan en un corto espacio de tiempo. La deduplicación es útil para métricas correctas, facturación e integridad de datos en pipelines de streaming.

Requisitos previos

  • Cuenta y acceso a una plataforma de streaming que permita operaciones por ventana/estado (p. ej.: Azure Stream Analytics, Apache Flink, Kafka Streams).
  • Flujo de eventos con un identificador único por entidad (p. ej.: event_id, user_id) y timestamp.
  • Editor/terminal para probar queries/código y ver logs.

Paso 1: comprender el problema y la estrategia

¿Por qué debemos deduplicar? En Real-Time Analytics, los eventos duplicados surgen por reenvíos, fallos de red o entrega con at-least-once. La estrategia común es usar una ventana temporal + almacenamiento de estado que registre los event_id ya procesados durante esa ventana. Vamos a implementar una deduplicación “por ventana de tiempo” que acepta el primer evento por event_id dentro de X minutos.

Paso 2: definir el formato mínimo del evento

Empieza por garantizar que cada evento tiene: event_id (string), timestamp (ISO) y payload. Ejemplo JSON para pruebas locales:

{
  "event_id": "abc-123",
  "timestamp": "2026-08-05T12:34:56Z",
  "user_id": "u42",
  "action": "click"
}

Paso 3: implementar deduplicación simple con SQL en streaming

Si estás usando un motor que soporte SQL sobre streaming (Azure Stream Analytics, Flink SQL), usa una cláusula de ventana y una función de agregación para escoger el primer timestamp por event_id. Ejemplo conceptual (ajusta para tu plataforma):

-- Janela tumbling de 5 minutos, mantém apenas o primeiro evento por event_id
SELECT
  event_id,
  System.Timestamp() AS window_end,
  MIN(timestamp) as first_timestamp,
  ANY_VALUE(action) as action
FROM InputStream
GROUP BY
  TumblingWindow(minute, 5),
  event_id

Explicación: agrupa por event_id dentro de ventanas de 5 minutos; MIN(timestamp) determina el primer evento. ANY_VALUE(action) es un placeholder para devolver el payload asociado.

Paso 4: deduplicación con estado (ejemplo en pseudo-code estilo Flink)

Para escenarios donde quieras garantizar deduplicación más flexible (stateful), usa un state store con TTL. Ejemplo en pseudo-code que ilustra la lógica:

// Para cada evento recibido
onEvent(event) {
  key = event.event_id
  now = event.timestamp
  if (!state.exists(key) || state.get(key) < now - dedupTTL) {
    // no visto dentro del TTL → procesar y grabar marca
    process(event)
    state.put(key, now)
  } else {
    // evento duplicado dentro del TTL → ignorar
    drop(event)
  }
}

// state tem TTL configurado para dedupTTL (ex.: 5 minutos)

Explicación: el state guarda el último timestamp visto por event_id; si el evento es más reciente que el TTL, se acepta y actualiza el estado, en caso contrario se ignora.

Paso 5: optimizar para memoria y escala

Errores comunes: guardar todos los event_id sin expirar; usar TTL demasiado largo; no particionar por clave. Buenas prácticas: elegir un TTL adecuado (p. ej.: 5–15 minutos), usar compresión/hash de la clave cuando haya gran cardinalidad, y particionar el stream por event_id para distribuir el estado.

Paso 6: gestionar idempotencia en el downstream

Incluso con deduplicación, considera la idempotencia en el sistema de destino (p. ej.: upserts por event_id). Si el destino soporta deduplicación nativa (p. ej.: índices únicos), combina ambas aproximaciones para mayor robustez.

Verificar el resultado

Prueba con un pequeño lote de eventos donde algunos tienen el mismo event_id dentro de la ventana TTL: espera recibir solo el primero. Los logs de procesamiento deben mostrar 'process' para el primero y 'drop' para los duplicados. Verifica métricas: número de eventos ingeridos vs eventos procesados. Si usas un motor SQL, ejecuta queries sobre la salida y confirma que cada event_id aparece como máximo una vez por ventana.

Conclusión

Has implementado deduplicación en Real-Time Analytics usando ventanas y/o estado con TTL — esto reduce falsos recuentos y mejora la integridad de los datos. Próximos pasos: integrar con tu sistema de mensajería (Kafka/Event Hubs), probar en carga y afinar el TTL. Consejo: ¿cuál es el trade-off entre un TTL corto y la pérdida de eventos legítimos — qué TTL tiene sentido para tu caso?