Designing Data Pipelines for Failure — From Data Quality Gates to Quarantine, Recovery and Safe Publication
Un pipeline terminé avec succès n’est pas nécessairement un pipeline qui a produit des données correctes.
Cette distinction paraît évidente lorsqu’elle est formulée ainsi. Dans la pratique, elle reste pourtant à l’origine d’une grande partie des incidents Data : les traitements sont passés au vert, les fichiers ont été chargés, les tables ont été alimentées, le modèle sémantique a été rafraîchi — et malgré cela, le résultat présenté au métier est faux.
Imaginons un cas simple.
Une entreprise consolide chaque nuit les commandes provenant de son ERP et de sa plateforme e-commerce. À 6 h 15, 100 000 transactions sont ingérées. Les transformations s’exécutent normalement. À 6 h 52, le pipeline passe au vert. À 7 h, le tableau de bord commercial est actualisé.
Techniquement :
PIPELINE STATUS : SUCCESS
Mais une évolution effectuée la veille dans l’un des systèmes sources a modifié le mapping du client. Dix-huit pour cent des commandes possèdent désormais un customer_id vide.
Le pipeline a fonctionné.
Le Data Product, lui, est incorrect.
C’est précisément ici que doit commencer la réflexion sur la fiabilité d’une plateforme Data.
1. Un pipeline fiable doit décrire son échec avant de décrire son succès
La représentation traditionnelle d’un pipeline est généralement linéaire :
SOURCE
→ INGEST
→ BRONZE
→ TRANSFORM
→ SILVER
→ AGGREGATE
→ GOLD
→ PUBLISH
Elle décrit parfaitement le happy path.
Elle nous renseigne beaucoup moins sur le comportement du système lorsque quelque chose se passe mal.
- Que se produit-il si la source ne répond pas ?
- Que se produit-il si 200 lignes sur 10 millions sont invalides ?
- Doit-on arrêter le traitement ?
- Doit-on conserver ces lignes ?
- Peut-on publier les autres ?
Que se produit-il si le traitement Gold s’exécute correctement mais produit un agrégat statistiquement aberrant ?
Et surtout : faut-il remplacer la version Gold actuellement consommée par une nouvelle version dont nous ne sommes pas certains ?
Une architecture résiliente devrait être capable de répondre à ces questions avant le premier incident de production.
La philosophie que je propose consiste donc à compléter le chemin nominal par une politique explicite d’échec et de reprise.
Une représentation simplifiée pourrait être :
SOURCE
↓
BRONZE
✓ → SILVER
✗ → ↻ RETRY SOURCE
→ ■ STOP si échec persistant
SILVER
✓ → GOLD
✗ → QUARANTINE
→ FIX
→ ↻ SILVER
GOLD
✓ → PUBLISH
✗ → ↩ KEEP PREVIOUS GOLD
→ ALERT
→ NO PUBLISH
Cette notation n’a pas vocation à remplacer BPMN, UML, les diagrammes d’architecture ou les représentations natives des orchestrateurs.
Elle poursuit un objectif beaucoup plus simple : rendre immédiatement visible la politique opérationnelle associée à chaque échec.
Et cette politique n’est pas nécessairement identique d’une couche à l’autre.
2. Bronze, Silver et Gold : trois couches, trois significations de l’échec
L’architecture Medallion constitue un cadre pratique pour raisonner sur cette question.
Databricks définit Bronze comme la couche de données brutes, Silver comme la couche de nettoyage et de validation, et Gold comme la couche enrichie destinée notamment aux usages métier. La documentation illustre d’ailleurs explicitement la mise en quarantaine d’enregistrements invalides dans Silver.
Microsoft reprend aujourd’hui cette progression dans les architectures Fabric : conservation des données sources en Bronze, nettoyage et conformité en Silver, puis données organisées pour l’analytique en Gold.
Mais cette progression de la donnée implique également une progression de responsabilité.
Bronze : préserver avant de corriger
Bronze se trouve au plus près de la source.
Son premier rôle n’est pas de rendre la donnée parfaite. Il consiste à capturer suffisamment fidèlement ce qui a été reçu pour permettre audit, investigation et reconstruction.
Une politique raisonnable peut donc être :
BRONZE ✗
→ ↻ RETRY SOURCE
→ ■ STOP
→ ALERT
Si une API répond momentanément par une erreur réseau, quelques nouvelles tentatives peuvent être appropriées.
Si la source reste indisponible, continuer artificiellement le pipeline avec une ingestion incomplète peut être plus dangereux que de l’arrêter.
Cette conservation du brut possède également une conséquence fondamentale : les couches aval doivent pouvoir être reconstruites.
Databricks recommande précisément de persister les données Bronze afin que les couches suivantes puissent être recréées à partir de cette source lorsque cela est nécessaire.
Le retry ne suffit donc pas.
Il faut également penser :
RETRY
REPLAY
CHECKPOINT
RUN_ID
SOURCE_TIMESTAMP
INGESTION_TIMESTAMP
Un traitement réellement rejouable doit savoir ce qu’il a déjà traité, ce qu’il doit retraiter et comment éviter qu’un replay ne crée artificiellement des doublons.
Nous arrivons alors rapidement au concept d’idempotence : répéter une opération ne devrait pas corrompre son résultat.
Silver : corriger, isoler, qualifier
Silver est différent.
Nous ne sommes plus seulement en train de capturer ce que la source nous donne. Nous cherchons à produire une donnée normalisée, dédupliquée, conforme et réutilisable.
C’est ici que la Data Quality devient particulièrement visible.
SILVER
→ CHECK
✓ → CONTINUE
✗ → QUARANTINE
→ FIX
→ ↻ REPLAY
Mais un point mérite une attention particulière :
quarantaine ne signifie pas nécessairement rejet du dataset entier.
Une anomalie peut concerner :
ROW
BATCH
PARTITION
FILE
TABLE
DATASET
PIPELINE
Supposons que 847 commandes sur 100 000 contiennent un code postal inconnu.
Une politique pourrait être :
VALID : 99 153 → SILVER
INVALID : 847 → QUARANTINE
DQ EVENT → LOG
SEVERITY → WARNING
Les 99 153 lignes conformes continuent.
Les 847 autres sont isolées physiquement avec suffisamment de contexte pour être comprises puis rejouées.
Mais changeons une seule chose.
Ces 847 lignes sont maintenant des opérations financières pour lesquelles le montant comptable ne correspond pas au détail des écritures.
Le volume d’erreurs est identique.
La décision peut être radicalement différente :
847 CRITICAL FINANCIAL VIOLATIONS
→ ■ BLOCK
→ ALERT
→ NO DOWNSTREAM PROCESSING
La proportion de données invalides ne suffit donc pas à déterminer la réaction.
La criticité de la règle compte autant que le volume de l’anomalie.
3. Data Pipeline et Data Quality Pipeline ne sont pas la même chose
Cette distinction est, à mon sens, structurante.
Le Data Pipeline transporte et transforme la donnée :
SOURCE
→ BRONZE
→ SILVER
→ GOLD
→ PUBLISH
Le Quality Control Flow évalue cette donnée et détermine ce qu’elle est autorisée à devenir :
CHECK
→ CLASSIFY
→ DECIDE
→ ACT
→ TRACE
Les deux sont intimement liés, mais leurs responsabilités ne sont pas identiques.
On peut les représenter ensemble :
QUALITY CONTROL FLOW
┌────────┴────────┐
↓ ↓
SOURCE → BRONZE → SILVER → GOLD → PUBLISH
│ │ │
DQ DQ DQ
Le Data Pipeline produit un Data Product.
Le Quality Control Flow produit quelque chose de différent : des Quality Evidence, autrement dit les éléments permettant de déterminer le niveau de confiance associé au produit.
On obtient alors :
DATA PIPELINE
→ DATA PRODUCT
QUALITY CONTROL FLOW
→ QUALITY EVIDENCE
et finalement :
DATA PRODUCT
+
QUALITY EVIDENCE
↓
CERTIFICATION GATE
↓
PUBLISH
Cette distinction permet de comprendre une situation qui devrait être parfaitement normale dans une plateforme mature :
Technical Status : SUCCESS
Quality Status : CRITICAL
Publication : BLOCKED
- Le code s’est exécuté.
- Spark n’a pas planté.
- SQL n’a retourné aucune erreur.
- L’orchestrateur affiche vert.
Pourtant, la donnée ne satisfait pas les critères nécessaires à sa publication.
C’est une information différente.
PIPELINE SUCCESS ≠ DATA QUALITY SUCCESS
4. Détecter n’implique pas nécessairement de bloquer
Toutes les règles de qualité ne doivent pas interrompre le pipeline.
C’est ici qu’il devient utile de distinguer Data Quality passive et Data Quality active.
Le contrôle passif
Un contrôle passif observe et qualifie une anomalie sans modifier physiquement le parcours de la donnée.
CHECK
↓
! WARNING
↓
TAG
→ LOG
→ ALERT
→ CONTINUE
Prenons une table CUSTOMER.
Le taux habituel de phone_number manquant oscille entre 1,8 % et 2,3 %.
Ce matin :
NULL RATE phone_number = 2.7 %
Cela mérite peut-être d’être surveillé.
Cela ne mérite probablement pas d’arrêter l’ensemble de la chaîne commerciale.
La donnée peut rester telle quelle, mais le système produit une information de qualité :
RULE : CUSTOMER_PHONE_COMPLETENESS
EXPECTED : >= 97.5 %
OBSERVED : 97.3 %
SEVERITY : WARNING
ACTION : TAG + LOG
PIPELINE : CONTINUE
L’étiquetage peut être matérialisé de différentes manières : métadonnée, colonne de statut, table de résultats DQ, événement d’observabilité ou catalogue.
Le principe reste identique :
nous signalons l’anomalie sans modifier la donnée.
Le contrôle actif
Le contrôle actif intervient au contraire sur le devenir de la donnée.
CHECK
↓
✗ INVALID
↓
QUARANTINE
↓
FIX
↓
↻ REPLAY
Une quarantaine doit idéalement préserver :
ORIGINAL DATA
RULE VIOLATED
ERROR REASON
RUN_ID
SOURCE
TIMESTAMP
SEVERITY
REPROCESSING STATUS
Sans cela, la quarantaine devient rapidement un cimetière de données que personne ne sait reconstruire.
Le contrôle bloquant
Il existe enfin une troisième catégorie opérationnelle :
CHECK
↓
■ CRITICAL
↓
STOP
→ ALERT
→ INVESTIGATE
→ FIX
→ ↻ RESTART
Une disparition d’une colonne contractuelle, une rupture d’intégrité financière ou une chute brutale du volume d’une source critique peuvent justifier ce comportement.
Nous obtenons donc trois politiques distinctes :
OBSERVE
! → TAG + LOG + ALERT → CONTINUE
ISOLATE
✗ → QUARANTINE → CONTINUE VALID DATA
↘ FIX → ↻ REPLAY
BLOCK
■ → STOP → ALERT → FIX → ↻ RESTART
Cette distinction existe également dans les mécanismes proposés par certaines plateformes. Les Materialized Lake Views de Microsoft Fabric permettent par exemple d’associer des actions à une violation de contrainte : FAIL arrête le refresh tandis que DROP poursuit le traitement en éliminant les enregistrements concernés.
L’outil change.
Le problème architectural reste le même :
Que sommes-nous autorisés à faire lorsqu’une règle est violée ?
5. Gold : protéger la publication, pas seulement le traitement
Gold nécessite une politique encore différente.
Cette couche est susceptible d’alimenter :
- des tableaux de bord ;
- des modèles sémantiques ;
- des API ;
- des modèles ML ;
- des exports réglementaires ;
- des applications opérationnelles ;
- d’autres Data Products.
Un échec Gold ne doit donc pas nécessairement détruire le dernier état valide.
Imaginons :
GOLD v41
STATUS : CERTIFIED
La nuit suivante, le pipeline calcule GOLD v42.
Les jobs s’exécutent, mais le contrôle de cohérence constate :
Yesterday Revenue : 12.4 M€
Today Revenue : 3.1 M€
Variation : -75 %
La variation peut être réelle.
Mais elle mérite d’être validée avant publication.
La mauvaise stratégie serait :
GOLD v41
→ OVERWRITE
→ GOLD v42
→ DISCOVER ERROR
Une stratégie plus défensive consiste à séparer construction et publication :
BUILD GOLD v42
→ VALIDATE
✓ → CERTIFY
→ PUBLISH v42
✗ → REJECT v42
→ ↩ KEEP GOLD v41
→ ALERT
→ NO PUBLISH
L’échec de production ne devient alors pas automatiquement un échec de service.
Cette logique introduit plusieurs concepts importants :
VERSIONING
ATOMIC PUBLICATION
CERTIFICATION
ROLLBACK
LAST KNOWN GOOD STATE
Et surtout une nouvelle distinction :
PROCESS DATA ≠ PUBLISH DATA
6. La Data Quality doit commencer avant le premier pipeline
Une plateforme robuste ne devrait pas découvrir sa politique de qualité au moment du premier incident.
Avant même l’implémentation, plusieurs questions devraient être explicites.
Le contrat
Qu’attendons-nous de la donnée ?
SCHEMA
TYPE
NULLABILITY
UNIQUENESS
REFERENTIAL INTEGRITY
FRESHNESS
VOLUME
BUSINESS RULES
La sévérité
Toutes les règles ne sont pas équivalentes.
INFO
WARNING
ERROR
CRITICAL
L’action
INFO → LOG
WARNING → TAG + ALERT + CONTINUE
ERROR → QUARANTINE
CRITICAL → BLOCK
Cette correspondance ne doit toutefois pas être codée universellement : elle dépend du Data Product et de son contexte métier.
L’ownership
Une alerte sans responsable n’est pas réellement une alerte.
Chaque règle importante devrait pouvoir répondre à :
À QUI APPARTIENNENT LES DONNÉES ?
À QUI APPARTIENT LA RÈGLE ?
QUI REÇOIT L’ALERTE ?
QUI PEUT DÉBLOQUER L’ACCÈS ?
QUI VALIDERA LA CORRECTION ?La reprise
Avant même de lancer le traitement :
PEUT-ON RÉESSAYER ?
PEUT-ON REJOUER ?
À PARTIR D'OÙ ?
AVEC QUELLE VERSION ?
SANS DOUBLON ?Le replay devrait être une capacité d’architecture, pas une procédure improvisée un dimanche matin.
7. L’observabilité : transformer les contrôles en système exploitable
Une règle de qualité qui écrit simplement :
ERROR
dans un fichier de log apporte peu de valeur opérationnelle.
Un événement de qualité devrait fournir suffisamment de contexte pour être exploitable.
Par exemple :
RUN_ID
PIPELINE
DATASET
LAYER
RULE
SEVERITY
EXPECTED
OBSERVED
FAILED_ROWS
TOTAL_ROWS
TIMESTAMP
ACTION
OWNER
STATUS
Nous pouvons alors suivre des métriques telles que :
DQ_PASS_RATE
FAILED_RECORD_COUNT
QUARANTINE_RATE
FRESHNESS_DELAY
VOLUME_DEVIATION
RETRY_COUNT
TIME_TO_RECOVERY
Mais attention : plus de logs ne signifie pas plus d’observabilité.
Si 80 000 lignes violent la même règle et génèrent 80 000 notifications, nous avons créé du bruit.
Une bonne stratégie doit prévoir :
AGGREGATION
DEDUPLICATION
THRESHOLDS
SEVERITY
ROUTING
ESCALATION
Les outils d’observabilité classiques deviennent alors utiles.
Prometheus peut porter les métriques. Grafana peut interroger des métriques, logs ou bases SQL et créer des règles d’alerte. Ses règles peuvent inclure conditions, périodes d’évaluation, labels, annotations et politiques de notification.
Loki peut compléter cette approche pour les logs, avec des alertes déclenchées à partir de requêtes LogQL lorsque certaines conditions sont dépassées.
Mais l’observabilité Data nécessite encore une information supplémentaire :
d’où vient cette donnée et quels produits sont impactés ?
C’est le rôle du lineage.
Ainsi, une anomalie détectée sur :
ERP.CUSTOMER
devrait idéalement permettre d’identifier :
ERP.CUSTOMER
↓
BRONZE_CUSTOMER
↓
SILVER_CUSTOMER
↓
GOLD_SALES
↓
SEMANTIC_MODEL_SALES
↓
EXECUTIVE_DASHBOARD
Nous ne surveillons plus uniquement un pipeline.
Nous surveillons l’impact potentiel de sa défaillance.
8. À quoi ressemble alors une plateforme complète ?
Nous pouvons maintenant réunir les deux flux.
QUALITY CONTROL FLOW
┌────────────────────────────┐
│ │
↓ ↓
SOURCE → BRONZE → DQ GATE → SILVER → DQ GATE → GOLD → CERTIFY → PUBLISH
│ │ │ │ │
│ │ │ │ │
↓ ↓ ↓ ↓ ↓
LOGS EVENTS QUARANTINE METRICS QUALITY EVIDENCE
│ │ │ │ │
└──────────┴──────────┴─────────┴────────┘
↓
OBSERVABILITY
↓
DASHBOARD / ALERTING
↓
OPERATIONS
Dans Microsoft Fabric, par exemple, une implémentation peut associer OneLake, Lakehouse/Warehouse, Data Factory, notebooks, Materialized Lake Views, monitoring et lineage. Les architectures de référence Microsoft recommandent également le contrôle de version, les validations lors des déploiements et une propriété claire des différents artefacts.
Mais l’architecture conceptuelle n’est pas spécifique à Fabric.
Elle peut être transposée sur Databricks, Snowflake, AWS, GCP ou sur une plateforme entièrement open source.
C’est précisément ce que nous allons vérifier.
9. Construire le même système avec des composants open source
Un laboratoire pertinent ne doit pas chercher à reproduire une plateforme Cloud entière.
Il doit démontrer les propriétés que nous venons de définir.
Une première architecture pourrait s’appuyer sur :
POSTGRESQL / FILES
↓
DAGSTER
↓
BRONZE
↓
DQ CHECKS
↓
SILVER
↓
DQ CHECKS
↓
GOLD
↓
CERTIFICATION GATE
↓
PUBLISH
avec parallèlement :
DQ EVENTS ──────┐
PIPELINE LOGS ──┤
METRICS ────────┼→ PROMETHEUS / LOKI
LINEAGE ────────┤
↓
GRAFANA
↓
ALERT
Le choix définitif des composants devra rester pragmatique. Dagster ou Airflow peuvent assurer l’orchestration ; dbt peut porter une partie des transformations et tests ; Great Expectations ou Soda peuvent formaliser des contrôles Data Quality ; OpenLineage peut fournir une représentation standardisée du lineage ; Prometheus, Loki et Grafana peuvent prendre en charge une partie de l’observabilité.
L’objectif n’est surtout pas :
MORE TOOLS = BETTER ARCHITECTURE
mais :
MINIMUM STACK
+
EXPLICIT POLICIES
+
REPRODUCIBLE FAILURE
=
USEFUL LAB
10. Le test le plus important : casser volontairement la plateforme
Une plateforme de démonstration qui ne traite que des données parfaites ne démontre presque rien sur sa résilience.
Notre laboratoire devra donc provoquer ses propres incidents.
Run 01 — fonctionnement nominal
INPUT : 100 000 rows
BRONZE ✓
SILVER ✓
GOLD ✓
CERTIFY ✓
→ PUBLISH GOLD v1
Run 02 — anomalie mineure
Trois commandes possèdent un champ optionnel incorrect.
3 / 100 000 INVALID
→ ! TAG
→ LOG
→ CONTINUE
→ PUBLISH GOLD v2
Le système détecte l’anomalie sans perturber inutilement le service.
Run 03 — quarantaine
847 lignes violent une règle Silver.
99 153 VALID
→ CONTINUE
847 INVALID
→ QUARANTINE
→ ALERT
Après correction :
QUARANTINE
→ FIX
→ ↻ REPLAY
→ VALIDATE
→ MERGE
Nous vérifions ici la capacité réelle de reprise.
Run 04 — rupture de contrat
La source supprime une colonne obligatoire.
SCHEMA CHECK ✗
→ ■ STOP
→ ALERT
→ NO SILVER
→ NO GOLD
Le système préfère explicitement l’indisponibilité temporaire à la fabrication silencieuse d’une donnée incorrecte.
Run 05 — Gold incorrect
Le traitement fonctionne mais les contrôles détectent une anomalie critique.
BUILD GOLD v3 ✓
QUALITY GATE ✗
→ REJECT v3
→ ↩ KEEP GOLD v2
→ ALERT
→ NO PUBLISH
C’est probablement le scénario le plus important de l’ensemble.
Le pipeline technique a réussi.
Le système de qualité a refusé la publication.
La production continue à servir la dernière version certifiée.
Run 06 — correction et replay
FIX
→ ↻ REPLAY
→ CHECK
→ CERTIFY
→ PUBLISH GOLD v3
L’incident est clos seulement lorsque la donnée corrigée a franchi de nouveau les contrôles.
11. Quelques principes émergent
Après avoir séparé les différents comportements, plusieurs règles deviennent visibles.
MOVE DATA
≠
TRUST DATA
Transporter correctement une donnée ne dit rien de sa validité métier.
DETECT ERROR
≠
BLOCK PIPELINE
Une anomalie peut être observée sans interrompre le traitement.
DETECT ERROR
≠
QUARANTINE DATA
La quarantaine est une décision opérationnelle, pas la conséquence automatique d’un contrôle négatif.
PIPELINE SUCCESS
≠
DATA QUALITY SUCCESS
L’exécution technique et la qualité du produit doivent pouvoir posséder des statuts différents.
PROCESS DATA
≠
PUBLISH DATA
Produire une nouvelle version et l’exposer aux consommateurs devraient être deux décisions séparables lorsque la criticité du produit le justifie.
Et enfin :
FAILURE
≠
DATA LOSS
Un échec correctement conçu doit pouvoir conduire à un retry, un replay, une quarantaine, un rollback ou au maintien du dernier état certifié.
Conclusion - Reliability is a policy, not a tool
La fiabilité d’une plateforme Data ne vient pas de l’existence d’une couche Bronze, Silver ou Gold.
Elle ne vient pas davantage du choix d’Airflow, Fabric, Databricks, dbt, Great Expectations ou Grafana.
Ces outils permettent d’implémenter des mécanismes.
Ils ne décident pas à notre place quelle politique appliquer lorsque la donnée devient incertaine.
C’est cette politique qui doit être conçue.
À chaque étape, une plateforme devrait pouvoir répondre à quelques questions simples :
- Que considérons-nous comme correct ?
- Que faisons-nous lorsqu’une anomalie apparaît ?
- Pouvons-nous continuer ?
- Devons-nous isoler ?
- Devons-nous arrêter ?
- Pouvons-nous rejouer ?
- Quelle version reste disponible pendant l’incident ?
- Qui est alerté ?
Et surtout : quelles preuves exigeons-nous avant d’autoriser une donnée à devenir un produit publié ?
Le pipeline complet n’est donc plus simplement :
SOURCE
→ BRONZE
→ SILVER
→ GOLD
Il devient :
INGEST
→ VALIDATE
→ TRANSFORM
→ VALIDATE
→ CERTIFY
→ PUBLISH
→ OBSERVE
→ RECOVER
Et autour de chaque transition existe désormais une politique :
PASS
OBSERVE
ISOLATE
BLOCK
RETRY
REPLAY
ROLLBACK
NO PUBLISH
C’est probablement là que se situe la différence entre une chaîne de traitements qui fonctionne la plupart du temps et une véritable plateforme Data industrielle :
la première sait comment traiter les données lorsqu’elles sont correctes ; la seconde sait également exactement quoi faire lorsqu’elles ne le sont pas.