Tu pipeline de medición pierde eventos en el pico de tráfico y los números de atribución nunca cuadran con los logs del bidder. Son dos fallos detrás de un mismo síntoma: eventos que nunca llegaron, en una costura que nadie contó, y eventos que llegaron y se contaron bajo otra regla. Así se construyen las costuras, las claves, la ventana de llegadas tardías y el puente de conciliación.
Un pipeline de eventos que pierde eventos en el pico de tráfico y nunca cuadra con los logs del bidder puede ser dos fallos detrás de un mismo síntoma. Uno es de transporte: eventos creados que nunca aterrizaron, en una costura que nadie contó. El otro es de definición: eventos que sí aterrizaron y se contaron bajo una regla distinta a la del registro de subasta.
El planteamiento habitual - el pipeline descarta eventos, así que reconstruye el pipeline - arregla como mucho uno de ellos. Lo que sigue separa los dos y dice qué produce una conciliación, que no es igualdad. Los valores por defecto que se citan abajo son los de Kafka en el lado del transporte y los de ClickHouse en el lado del almacenamiento.
La respuesta corta es estructural: un identificador por subasta transportado de extremo a extremo, un contador a ambos lados de cada salto y una conciliación sobre una ventana que ya se ha cerrado. Lo que amBrain puede sustentar públicamente es el trabajo de AdTech: desarrollo de DSP, plataformas de real-time bidding e ingeniería de ad exchange. En cualquier stack de RTB ese es el lado del que vienen los registros de puja, win e impresión. El pipeline de abajo se describe desde la mecánica del problema, no desde un caso nuestro.
El primer fallo es la pérdida: el evento se creó y nunca llegó, en un salto concreto, por un motivo concreto. Un beacon que nunca salió de la página, un edge reiniciado a mitad de despliegue, un buffer de producer que se llenó, un consumer que confirmó su offset antes de procesar.
El segundo no es un fallo en absoluto. El lado de la medición cuenta un evento iniciado en el cliente; el bidder registra un resultado de subasta del lado del servidor. Uno es una adjudicación, el otro una observación de lo que le pasó. Las guías de medición del MRC tratan pre-fetch, pre-render y auto-refresh como cosas distintas que hay que detectar y divulgar: una regla de conteo, no un fallo de transporte. Distinguir los dos cuesta una consulta y algo de paciencia.
Hasta que esa curva exista, los dos lados del argumento son opiniones. Después, su forma decide qué mitad de este artículo aplica, y las mitades no son excluyentes.
Hay siete sitios donde un evento publicitario se crea y luego deja de existir en silencio, más un ajuste que parece una garantía y no lo es.
La regla es una regla de reporting, no de ingeniería: una pérdida se atribuye a una costura con nombre, o no se atribuye en absoluto. Dos alarmas mantienen visibles las costuras silenciosas - el consumer lag medido en tiempo frente a la retención, y una política de reset que falla en vez de saltar.
Una clave de deduplicación no es una clave primaria cómoda elegida en el destino. Se asigna aguas arriba de cualquier reintento, en el momento de la subasta o cuando se crea el evento, y el receptor nunca se la inventa. Los timestamps de llegada quedan fuera: un reintento lleva un timestamp de llegada nuevo y una clave nueva.
La clave tiene que ser idéntica en todos los intentos, lo que decide sus partes: el exchange o seat, el identificador de subasta, el identificador de impresión y el tipo de evento. Particiona el topic por esa clave, para que los reintentos caigan juntos y el orden por clave sobreviva. Esa instrucción es solo para el transporte: la misma palabra aplicada al almacén columnar da una partición por evento, y el insert muere en el límite por bloque. Particiona el almacenamiento por tiempo y ordena por la clave.
Así que la forma que funciona es transporte at-least-once con claves idempotentes. La deduplicación en escritura mantiene razonable la factura de almacenamiento; la deduplicación en lectura es la que hace correcto el número. Los merges nunca combinan parts de particiones distintas, así que un duplicado que cae en la partición siguiente solo se resuelve cuando una consulta lo pide.
Bajo sobrecarga un sistema tiene tres opciones: frenar al producer, descartar con un contador, o perder en silencio. Solo la tercera es inaceptable, y es el comportamiento por defecto del código al que nunca se le hizo la pregunta. La pérdida en el pico es una cola que creció hasta agotar la memoria, o un acuse emitido antes de la durabilidad.
Un descarte con un contador etiquetado es una cantidad conocida que se puede conciliar después. Un descarte sin él no son datos perdidos, es un número perdido.
La guía de implementación de OpenRTB lo dice directamente: la secuencia que va de la solicitud de anuncio a la subasta y de ahí al renderizado y la facturación es fundamentalmente no transaccional. Hay demasiadas partes entre los dos recuentos.
El retraso es lo esperado, no la excepción. La solicitud de puja puede llevar una caducidad de la impresión y la puja, el retraso que el bidder tolera, y la misma guía da reglas generales que van del orden de un minuto para web a mucho más para formatos in-app cacheados y vídeo con stitching.
Ninguno de los dos campos es un contrato. La guía dice claramente que una notificación de facturación que llega más tarde que la caducidad declarada por el bidder puede seguir siendo facturable - una discusión de política entre bidder y exchange antes que algo que imponga el protocolo.
Un evento que llega después de la ventana no es un defecto del pipeline, es una propiedad del medio. La única elección real es si el número se mueve en público mientras la ventana está abierta, o se mueve en privado después.
Los identificadores que el exchange sustituye en las URLs de notificación y de tracking son el identificador de subasta de la solicitud de puja, el identificador de impresión y, cuando el bidder acuñó uno, el identificador de puja. Ninguno de los tres es una clave por sí solo.
La especificación llama al identificador de subasta único por exchange, no único a nivel global: dos exchanges pueden entregarte la misma cadena el mismo día. El identificador de impresión solo es único dentro de su propia solicitud de puja, a menudo el literal 1. El identificador de puja es opcional.
La clave que aguanta es la compuesta: el exchange o seat a través del cual transaccionaste, más el identificador de subasta, más el identificador de impresión. Acúñala del lado del bidder en el momento de la subasta, y trata cualquier cosa más corta como un prefijo y no como una clave.
Si esas macros faltan en los beacons, la conciliación a nivel de evento es imposible, y lo que queda es casar por tiempo, emplazamiento y creatividad. Lo que sí puedes construir es un puente de seis recuentos, cada uno nombrando su motivo de diferencia con el paso anterior.
Un ratio estable entre pasos es el objetivo y un movimiento sin explicación es la alarma. Dentro de un mismo sistema, los ratios por salto deben estar en uno, y cualquier desviación es la señal. Cruzando la frontera de la subasta a la medición, uno es la lectura sospechosa.
Los mismos contadores, leídos como ratios, convierten la pregunta en aritmética: aceptados sobre enviados, producidos sobre aceptados, consumidos sobre producidos, insertados sobre consumidos. Cuatro ratios en un gráfico dicen adónde fueron los eventos antes de que nadie abra un log. Añade un número de secuencia del lado del producer por fuente y partición, y un hueco pasa a ser evidencia en vez de sospecha.
Una pregunta que el puente no responde y un contrato sí: sobre cuál de estos números pagas. El vendedor contabiliza los ingresos sobre su propio evento facturable, el comprador hace su pacing sobre el suyo, y la guía trata una diferencia persistente como una conversación de soporte entre las partes.
Decide de antemano qué recuento es el sistema de registro del gasto, y a partir de qué diferencia una nota en el informe se convierte en un ticket con el exchange. El trabajo de arriba compra atribución de la pérdida, duplicados honestos y una conciliación explicada línea a línea. No compra lo siguiente.
Un pipeline que puede responder a esas preguntas de divulgación tiene un argumento de integridad. El que no puede tiene una opinión, y una opinión es lo que se discute al cierre de un trimestre.
El fallo contra el que merece la pena diseñar no es la hora que falta y arranca una investigación. Es la versión silenciosa: una costura que descarta sin contador, un insert confirmado antes de ser durable, y una conciliación sobre una ventana todavía abierta.
Lo que amBrain puede sustentar públicamente: amBrain es una empresa de ingeniería de software de Ereván, Armenia, que construye plataformas de trading de baja latencia, matching engines y sistemas de real-time bidding en Rust. amBrain lleva construyendo software desde 2019. Reconstruir un pipeline de medición no es el trabajo que se describe aquí. Si los números dejan de cuadrar en el lado del bidder y del exchange - los propios registros de puja, win e impresión -, esa es la conversación que merece la pena, y empieza por la curva de estabilización y no por una reconstrucción.
Traiga su arquitectura actual y el modo de fallo que le preocupa, y lo repasaremos juntos en media hora.