Par Andrew Tan
Les dérives de schéma et les changements en amont qui cassent sont la première cause des échecs silencieux des données — mais la plupart des contenus sur les pipelines se concentrent sur l'infrastructure, pas sur le comportement du système source
Connexe : Cet article couvre le Modèle 1 de notre analyse de 50 postmortems de pipelines de données d'Uber, Netflix, Stripe et d'autres. Les dérives de schéma représentaient 38% des incidents — la cause principale la plus courante que nous avons trouvée.
Le champ qui a changé de type un mardi
Une équipe que je connais gère la réconciliation des paiements pour une entreprise de commerce électronique de taille moyenne. Leur pipeline extrait les données de transaction d'un processeur de paiement tiers, les transforme et les charge dans leur entrepôt de données. Cela fonctionne sans incident depuis deux ans et demi.
Un mardi après-midi de novembre, le processeur de paiement a mis à jour discrètement son API. Un champ — transaction_amount — est passé d'une chaîne de caractères (car certains systèmes hérités représentent l'argent comme "47.50") à un flottant natif (47.50). Pas de versionnage. Pas d'avis de dépréciation. Pas d'email. La documentation a été mise à jour au cours de la semaine suivante.
Le pipeline n'a pas planté. Il a continué à fonctionner. Il a continué à traiter les transactions. Il a continué à signaler le succès.
Ce qu'il a cessé de faire, c'est de caster correctement. La transformation en aval supposait une entrée sous forme de chaîne et appliquait une expression régulière pour supprimer les symboles monétaires avant de convertir. Avec un flottant entrant, l'expression régulière ne correspondait à rien, la conversion produisait une valeur nulle, et chaque transaction des six heures suivantes avait un montant de zéro.
Six heures de transactions à zéro dollar, toutes affichées comme traitées. Personne ne l'a remarqué jusqu'à ce que le rapport de réconciliation quotidien sorte le lendemain matin et que les chiffres ressemblent à une erreur d'arrondi qui aurait englouti l'entreprise.
Je raconte cette histoire car elle illustre quelque chose que la plupart des écrits sur l'architecture des pipelines manquent : les échecs les plus effrayants ne viennent pas de votre infrastructure. Ils viennent des systèmes que vous ne contrôlez pas.
Trois types de changement en amont
Tous les changements en amont ne sont pas égaux. J'ai vu des équipes se brûler avec chacun d'eux, et ils nécessitent des défenses différentes.
Les changements additifs sont ceux que les fournisseurs annoncent comme "compatibles à rebours". De nouveaux champs apparaissent dans la réponse. Les champs existants restent les mêmes. En théorie, votre pipeline devrait être correct — vous n'utilisez pas les nouveaux champs. En pratique, les changements additifs cassent les pipelines lorsqu'ils atteignent des hypothèses implicites de taille (une réponse JSON dépasse maintenant une limite de tampon), lorsque des captures de schéma génériques commencent à capter des champs que vous n'attendiez pas, ou lorsque ce nouveau champ est nommé d'une manière qui entre en collision avec un champ que vous avez déjà dans votre table de destination.
Les changements cassants sont au moins honnêtes. Le champ est renommé. Le type change. Un point de terminaison est déprécié. Ceux-ci devraient être annoncés — et le sont généralement, pour les fournisseurs réputés. Mais "annoncé" ne signifie pas "pris en compte". L'annonce repose dans un résumé d'email que personne ne lit car l'équipe qui le reçoit n'est pas celle qui possède le pipeline, et au moment où la date de dépréciation arrive, l'ingénieur d'origine a déménagé dans une autre entreprise.
Les changements silencieux sont la situation du processeur de paiement. Le genre dont personne ne vous parle parce que, du point de vue du fournisseur, rien n'a changé. La sémantique est la même. Les données sont les mêmes. Seul le type a changé. Ou le codage. Ou le comportement de gestion des valeurs nulles. Les changements silencieux sont ceux qui se transforment en événements de corruption de données de six heures avant que quelqu'un ne s'en aperçoive.
La proportion de chaque type varie selon la maturité du fournisseur. Les API financières établies sont principalement des changements cassants avec de longues fenêtres de dépréciation. Les produits SaaS avec des cycles de publication rapides sont principalement silencieux et additifs. Les flux de données fournis par les partenaires — le genre peu glamour mais critique qui exécute des intégrations B2B — sont véritablement imprévisibles.

Pourquoi la plupart des pipelines échouent au mauvais niveau
Voici la chose à propos de la validation de schéma : presque tous les outils de pipeline modernes la supportent. Vous pouvez définir des schémas. Vous pouvez valider à l'ingestion. Vous pouvez rejeter les enregistrements mal formés.
La plupart des équipes ne le font pas, pour des raisons compréhensibles.
Aux premiers jours d'un pipeline, le schéma change constamment. Le système source est encore en développement. Une validation stricte échouerait au pipeline chaque fois qu'un champ est ajouté ou renommé lors d'une itération normale. Ainsi, la validation est désactivée, ou assouplie à "meilleur effort", et au moment où le pipeline atteint la production, personne ne se souvient de la resserrer.
Il y a aussi une division philosophique sur la façon dont les équipes pensent à l'application du schéma. La validation stricte du schéma semble défensive. Cela donne l'impression que vous construisez un mur qui cassera le pipeline chaque fois que le système source respirera. La gestion permissive semble pragmatique. Gérez ce que vous pouvez, laissez passer ce que vous ne pouvez pas, laissez la destination le comprendre.
Le problème avec la gestion permissive est qu'elle déplace la surface d'échec en aval et la rend invisible. Votre pipeline ne tombe pas en panne. Votre analytique ou application en aval traite silencieusement des données incorrectes. Et au moment où vous vous en apercevez — des jours plus tard, lorsqu'un rapport semble incorrect, ou qu'un utilisateur signale une divergence — les enregistrements corrompus ont été mélangés avec des enregistrements légitimes, aggravés par des transformations en aval, et peut-être même utilisés.
La validation de schéma au niveau du pipeline n'est pas une question d'être strict pour le plaisir de l'être. Il s'agit de rendre les échecs bruyants et précoces plutôt que silencieux et tardifs.
Les trois classes de défense
Après avoir observé suffisamment de ces incidents, j'ai constaté que les équipes qui gèrent les changements en amont avec grâce font trois choses de manière cohérente.
Validation de forme, pas seulement de types. La validation de type attrape la situation du processeur de paiement. Mais la validation de forme attrape les cas plus subtils : un champ requis devenant optionnel (et donc parfois absent), un tableau qui avait toujours un élément en a maintenant parfois zéro, un objet qui était plat devient maintenant imbriqué un niveau plus profond.
La distinction est importante car les erreurs de type produisent des échecs bruyants. Les incompatibilités de forme produisent des échecs silencieux. Un champ présent 99,9 % du temps et absent 0,1 % du temps produira un bug de gestion des valeurs nulles qui prendra des semaines à apparaître car il ne se déclenche que sur des types de transactions rares, ou des régions géographiques spécifiques, ou des méthodes de paiement de cas limite.
Surveillance de la dérive de schéma, pas seulement du statut des tâches. Le statut des tâches vous dit si le pipeline a fonctionné. La surveillance de la dérive de schéma vous dit si ce que le pipeline a traité aujourd'hui a la même forme que ce qu'il a traité hier.
Cela ne nécessite pas une plateforme d'observabilité sophistiquée. La version la plus simple est une vérification quotidienne qui hache le schéma inféré d'un échantillon d'enregistrements de chaque source et alerte si le hachage change. C'est rudimentaire mais efficace. La plupart des événements de dérive de schéma sont détectables par cette méthode en moins de 24 heures.
Des versions plus sophistiquées suivent les statistiques au niveau des champs : taux de valeurs nulles par champ, cardinalité par champ, distribution des types par champ. Lorsque le taux de valeurs nulles pour transaction_amount passe de 0,0 % à 0,1 %, quelque chose a changé en amont. Peut-être que c'est intentionnel. Peut-être que c'est un bug. Dans tous les cas, vous voulez le savoir avant que cela ne devienne un problème.
Séparer l'ingestion du traitement. C'est le modèle architectural qui achète le plus de temps lorsque des changements en amont se produisent. Si votre pipeline ingère des données brutes dans une zone d'atterrissage avant de les traiter, vous avez la possibilité de rejouer contre des données brutes historiques après avoir corrigé un problème de schéma. Si l'ingestion et le traitement sont couplés, vous perdez cette option.
La zone d'atterrissage brute n'a pas besoin d'être coûteuse ou complexe. Pour de nombreux cas d'utilisation, un stockage d'objets en mode append-only (S3, GCS, Azure Blob) avec JSON brut partitionné est suffisant. La couche de transformation lit à partir de la zone d'atterrissage, pas directement à partir de la source. Lorsque quelque chose tourne mal en amont, vous corrigez la transformation et rejouez. Les données sont toujours là.

Tests de contrat au niveau du pipeline : est-ce que ça vaut le coup ?
Vous entendrez parler des tests de contrat pilotés par le consommateur comme la solution "correcte" à ce problème. L'idée est que votre pipeline publie un contrat — voici les champs dont je dépends, voici les types que j'attends, voici ce que je considère comme un changement cassant — et le système source est censé valider contre ce contrat avant de déployer des changements.
Cela fonctionne bien lorsque vous contrôlez les deux côtés de l'intégration. Si vous intégrez des microservices internes, ou travaillez avec un fournisseur qui prend la stabilité de l'intégration au sérieux, les tests de contrat sont vraiment précieux. Des outils comme Pact les rendent réalisables.
Pour la majorité des intégrations que je vois en pratique — SaaS tiers, API de partenaires, flux de données de systèmes sur lesquels vous n'avez aucun contrôle — les tests de contrat sont une belle théorie. Vous ne pouvez pas contraindre un processeur de paiement à exécuter vos tests Pact avant de déployer. Vous ne pouvez pas négocier des droits de publication de contrat avec un fournisseur dont l'équipe juridique n'a jamais entendu parler de contrats pilotés par le consommateur.
Le cadre plus pratique est : que pouvez-vous faire de votre côté de la frontière pour détecter les changements et vous en remettre rapidement ?
Ce qui me ramène à la surveillance des schémas, aux zones d'atterrissage et à la validation au niveau du pipeline. Pas glamour. Pas la solution techniquement intéressante. Mais celle qui fonctionne réellement sur toute la gamme des scénarios en amont que vous rencontrerez.
La question à poser à chaque lancement d'intégration
J'ai commencé à poser une question à chaque revue de conception d'intégration : Quel est le processus lorsque cela change sans avertissement ?
Pas si. Quand.
Cela semble pessimiste. L'équipe d'intégration des partenaires le prend parfois personnellement. Mais la question force une conversation qui met presque toujours en lumière des hypothèses que personne n'avait rendues explicites : l'hypothèse que l'équipe du système source communiquera les changements cassants, l'hypothèse que quelqu'un dans l'équipe d'intégration lira le changelog, l'hypothèse que le pipeline peut tolérer X jours de données incorrectes avant que quelqu'un ne s'en aperçoive.
Ces hypothèses sont généralement fausses. Les rendre explicites vous donne une chance de concevoir autour d'elles.
La réponse à "que se passe-t-il lorsque cela change sans avertissement" devrait impliquer au minimum : où l'alerte se déclenche, qui la reçoit, à quelle vitesse l'équipe peut identifier quel champ a changé, et à quelle vitesse elle peut rejouer les données affectées à partir de la zone d'atterrissage brute. Si la réponse est "nous devrions enquêter et probablement appeler le fournisseur", le pipeline n'est pas prêt pour la production.
Où layline.io s'inscrit dans cela
L'évolution des schémas est l'une des choses auxquelles nous pensons beaucoup dans la façon dont layline.io gère le traitement des données. Lorsque vous traitez à la fois des pipelines batch et streaming — et la réalité est que la plupart des équipes exécutent les deux indéfiniment — le problème des changements en amont se complique. Un changement de schéma dans une source de streaming vous frappe en temps réel. Le même changement dans une source batch pourrait ne pas apparaître avant 24 heures.
Le modèle de traitement de layline.io vous soutient avec l'évolution des schémas grâce au routage explicite des versions : lorsqu'une nouvelle version de schéma est introduite, vous pouvez appliquer une logique et une validation séparées ou diriger ces enregistrements vers un flux séparé pour validation et traitement, plutôt que de les laisser contaminer votre chemin de traitement principal.
Ce n'est pas magique. Vous devez toujours concevoir votre intégration avec l'hypothèse que les choses en amont changeront. Mais cela signifie que lorsqu'elles changent, la surface d'échec est plus petite et le chemin de récupération est plus rapide.
Les équipes qui gèrent les changements en amont avec grâce ne sont pas celles avec l'infrastructure la plus sophistiquée. Ce sont celles qui ont cessé de supposer que le système source ne les surprendrait jamais.
Si votre équipe est confrontée à des dérives de schéma ou à la fiabilité des intégrations en amont, le moteur de traitement de layline.io gère l'évolution des schémas et la résilience des pipelines pour les charges de travail batch et en temps réel. La Community Edition est gratuite à explorer.
Andrew Tan est un entrepreneur en série et fondateur de layline.io, construisant une infrastructure de traitement de données d'entreprise qui gère à la fois les charges de travail batch et en temps réel à grande échelle.



