Votre pipeline de mesure perd des événements au pic de trafic et les chiffres d'attribution ne concordent jamais avec les logs du bidder. Ce sont deux pannes derrière un seul symptôme : des événements qui ne sont jamais arrivés, à un raccord que personne n'a compté, et des événements arrivés et comptés selon une règle différente. Voici comment se construisent les raccords, les clés, la fenêtre de retard et le pont de réconciliation.
Un pipeline d'événements qui perd des événements au pic de trafic et ne se réconcilie jamais avec les logs du bidder peut être deux pannes derrière un seul symptôme. La première est de transport : des événements créés et jamais arrivés, à un raccord que personne n'a compté. La seconde est définitionnelle : des événements arrivés et comptés selon une règle différente de celle de l'enregistrement d'enchère.
Le cadrage habituel - le pipeline perd des événements, donc reconstruisons le pipeline - en répare au plus un. Ce qui suit sépare les deux et dit ce que produit une réconciliation, ce qui n'est pas l'égalité. Les valeurs par défaut citées ci-dessous sont celles de Kafka côté transport et de ClickHouse côté stockage.
La réponse courte est structurelle : un identifiant par enchère porté de bout en bout, un compteur des deux côtés de chaque saut, et une réconciliation sur une fenêtre déjà close. Ce qu'amBrain peut étayer publiquement, c'est le travail AdTech : développement de DSP, plateformes d'enchères en temps réel et ingénierie d'ad exchange. Dans n'importe quelle stack RTB, c'est le côté d'où viennent les enregistrements de bid, de win et d'impression. Le pipeline ci-dessous est décrit à partir de la mécanique du problème, pas à partir d'un cas à nous.
La première panne est la perte : l'événement a été créé et n'est jamais arrivé, à un saut précis, pour une raison précise. Un beacon qui n'a jamais quitté la page, un edge redémarré en plein déploiement, un buffer de producteur qui s'est rempli, un consommateur qui a commité son offset avant le traitement.
La seconde n'est pas du tout une panne. Le côté mesure compte un événement initié par le client ; le bidder enregistre un résultat d'enchère côté serveur. L'un est une adjudication, l'autre une observation de ce qui lui est arrivé. Les lignes directrices de mesure du MRC traitent le pre-fetch, le pre-render et l'auto-refresh comme des éléments distincts à détecter et à divulguer : une règle de comptage, pas une panne de transport. Distinguer les deux coûte une requête et un peu de patience.
Tant que cette courbe n'existe pas, les deux camps de la discussion sont des avis. Ensuite, sa forme décide quelle moitié de cet article s'applique, et les deux moitiés ne s'excluent pas.
Il y a sept endroits où un événement publicitaire est créé puis cesse discrètement d'exister, plus un réglage qui ressemble à une garantie et n'en est pas une.
La règle est une règle de reporting, pas d'ingénierie : une perte est attribuée à un raccord nommé, ou n'est pas attribuée du tout. Deux alarmes gardent visibles les raccords silencieux - le lag du consommateur mesuré en temps face à la rétention, et une politique de réinitialisation qui échoue au lieu de sauter.
Une clé de déduplication n'est pas une clé primaire commode choisie à la destination. Elle est attribuée en amont de tout retry, au moment de l'enchère ou à la création de l'événement, et le récepteur n'en invente jamais. Les timestamps d'arrivée sont exclus : un retry porte une nouvelle heure d'arrivée et une nouvelle clé.
La clé doit être identique à chaque tentative, ce qui décide de ses composants : l'ad exchange ou le seat, l'identifiant d'enchère, l'identifiant d'impression et le type d'événement. Partitionnez le topic sur cette clé, pour que les retries atterrissent ensemble et que l'ordre par clé leur survive. Cette consigne ne vaut que pour le transport : le même mot appliqué à la base colonnaire donne une partition par événement, et l'insertion meurt sur la limite par bloc. Partitionnez le stockage par le temps, ordonnez par la clé.
La forme qui fonctionne est donc un transport at-least-once avec des clés idempotentes. La déduplication à l'écriture garde la facture de stockage raisonnable ; c'est la déduplication à la lecture qui rend le chiffre correct. Les merges ne combinent jamais des parts de partitions différentes : un doublon qui atterrit dans la partition suivante n'est donc résolu que lorsqu'une requête le demande.
En surcharge, un système a trois options : ralentir le producteur, délester avec un compteur, ou perdre en silence. Seule la troisième est inacceptable, et c'est le comportement par défaut d'un code à qui on n'a jamais posé la question. La perte au pic, c'est une file qui a grandi jusqu'à épuiser la mémoire, ou un acquittement émis avant la durabilité.
Un rejet doté d'un compteur étiqueté est une quantité connue, réconciliable plus tard. Un rejet sans compteur n'est pas une donnée perdue, c'est un chiffre perdu.
Les recommandations d'implémentation OpenRTB le disent directement : la séquence qui va de la demande publicitaire à l'affichage et à la facturation, en passant par l'enchère, n'est fondamentalement pas transactionnelle. Trop de parties se tiennent entre les deux décomptes.
Le délai est attendu plutôt qu'exceptionnel. La bid request peut porter une expiration d'impression, et le bid le délai que le bidder tolère ; les mêmes recommandations donnent des ordres de grandeur allant de l'ordre de la minute pour le web à bien plus pour les formats in-app mis en cache et la vidéo stitchée.
Aucun des deux champs n'est un contrat. Les recommandations le disent clairement : une notification de facturation qui arrive après l'expiration déclarée par un bidder peut rester facturable - une discussion de politique entre le bidder et l'ad exchange plutôt qu'une contrainte imposée par le protocole.
Un événement qui arrive après la fenêtre n'est pas un défaut du pipeline, c'est une propriété du média. Le seul vrai choix est de savoir si le chiffre bouge en public pendant que la fenêtre est ouverte, ou s'il bouge en privé après.
Les identifiants que l'ad exchange substitue dans les URL de notification et de tracking sont l'identifiant d'enchère issu de la bid request, l'identifiant d'impression et, là où le bidder en a généré un, l'identifiant de bid. Aucun des trois n'est une clé à lui seul.
La spécification qualifie l'identifiant d'enchère d'unique au niveau de l'ad exchange, pas d'unique au niveau mondial : deux ad exchanges peuvent vous remettre la même chaîne le même jour. L'identifiant d'impression n'est unique qu'à l'intérieur de sa propre bid request, souvent le littéral 1. L'identifiant de bid est optionnel.
La clé qui tient est la clé composite : l'ad exchange ou le seat par lequel vous avez transigé, plus l'identifiant d'enchère, plus l'identifiant d'impression. Générez-la côté bidder au moment de l'enchère, et traitez tout ce qui est plus court comme un préfixe et non comme une clé.
Si ces macros sont absentes des beacons, la réconciliation au niveau de l'événement est impossible, et il ne reste qu'un rapprochement sur le temps, l'emplacement et la créative. Ce que vous pouvez construire à la place, c'est un pont de six décomptes, chacun nommant sa raison de différer de l'étape précédente.
Un ratio stable entre étapes est l'objectif, et un mouvement inexpliqué est l'alarme. À l'intérieur d'un même système, les ratios de saut doivent valoir un, et tout écart est le signal. À la frontière entre l'enchère et la mesure, c'est un qui devient la lecture suspecte.
Les mêmes compteurs, lus comme des ratios, transforment la question en arithmétique : acceptés sur envoyés, produits sur acceptés, consommés sur produits, insérés sur consommés. Quatre ratios sur un même graphique disent où sont partis les événements avant que quiconque n'ouvre un log. Ajoutez un numéro de séquence côté producteur par source et par partition, et un trou devient une preuve plutôt qu'un soupçon.
Une question à laquelle le pont ne répond pas et à laquelle un contrat répond : sur lequel de ces chiffres vous payez. Le vendeur comptabilise son revenu sur son propre événement facturable, l'acheteur fait son pacing sur le sien, et les recommandations traitent un écart persistant comme une conversation de support entre les parties.
Décidez à l'avance quel décompte fait foi pour la dépense, et à partir de quel écart une note de rapport devient un ticket auprès de l'ad exchange. Le travail ci-dessus achète l'attribution des pertes, des doublons honnêtes et une réconciliation expliquée ligne par ligne. Il n'achète pas ce qui suit.
Un pipeline capable de répondre à ces questions de divulgation a une histoire d'intégrité. Celui qui ne le peut pas a un avis, et un avis, c'est ce sur quoi on se dispute en fin de trimestre.
La panne contre laquelle il vaut la peine de concevoir n'est pas l'heure manquante qui déclenche une enquête. C'est la version silencieuse : un raccord qui déleste sans compteur, une insertion acquittée avant d'être durable, et une réconciliation sur une fenêtre encore ouverte.
Ce qu'amBrain peut étayer publiquement : amBrain est une société d'ingénierie logicielle basée à Erevan, en Arménie, qui construit des plateformes de trading à faible latence, des matching engines et des systèmes de real-time bidding en Rust. amBrain construit des logiciels depuis 2019. Reconstruire un pipeline de mesure n'est pas un travail décrit ici. Si les chiffres cessent de concorder côté bidder et côté ad exchange - les enregistrements de bid, de win et d'impression eux-mêmes - c'est la conversation qui vaut la peine d'avoir lieu, et elle commence par la courbe de stabilisation plutôt que par une reconstruction.
Apportez votre architecture actuelle et le mode de défaillance qui vous inquiète : nous les passerons en revue ensemble en une demi-heure.