Le manifeste de la nuit et la balise du conteneur
Sur un terminal, deux systèmes d'information cohabitent sans se ressembler.
Le premier consolide chaque nuit le manifeste de cargaison : ce qui est entré, ce qui est sorti, ce qui reste sur le terre-plein. Il tourne à trois heures du matin, il traite la journée entière d'un bloc, et personne ne le regarde tant qu'il finit avant l'ouverture des bureaux.
Le second suit les conteneurs pendant qu'ils bougent. Une balise émet sa position et la température du groupe frigorifique toutes les quelques secondes. Si un conteneur réfrigéré dérive au-dessus de son seuil, l'alerte doit partir maintenant, pas dans le rapport de demain matin.
Les deux servent la même marchandise. Ils n'ont ni le même rythme, ni les mêmes outils, ni les mêmes modes de panne.
Une chaîne d'intégration se conçoit à partir du délai admissible entre le moment où un fait se produit et le moment où quelqu'un peut l'utiliser. Tout le reste en découle.
Les billets précédents traitaient des magasins où la donnée se pose : le compte de stockage, la base relationnelle, puis le magasin non relationnel. Celui-ci traite du transport entre ces magasins, qui est un métier à part entière.
La chaîne, en quatre temps
Sur le port, la marchandise suit toujours le même trajet : le quai, le terre-plein, l'entrepôt, puis le guichet où le client vient la retirer. Peu importe qu'elle arrive par navire, par train ou par camion, ces quatre étapes existent.
Une chaîne de données a la même ossature. On la découpe en ingestion, stockage, transformation et restitution. La confusion la plus fréquente en réunion de conception consiste à mélanger l'étape et l'outil : Data Factory n'est pas « la chaîne », c'est un orchestrateur d'ingestion et de transformation qui délègue le stockage à autre chose.
| Étape | La question posée | Ce qui la traite sur Azure |
|---|---|---|
| Ingestion | comment la donnée entre, et à quel rythme | Data Factory pour le lot, Event Hubs pour le flux |
| Stockage | où elle atterrit avant d'être exploitable | Data Lake Storage, comptes de stockage |
| Transformation | qui la nettoie, la joint et la met en forme | flux de données de mappage, Spark, Stream Analytics |
| Restitution | qui la lit, avec quelle latence et quel format | pools SQL, bases analytiques, rapports et API |
La différence entre le lot et le flux ne se joue pas à l'ingestion seule. Elle traverse les quatre étapes : le format de stockage change, le moteur de transformation change, et la façon de rejouer un traitement raté change du tout au tout.
Data Factory"] FLX["Ingestion en flux
Event Hubs"] ASA["Traitement de flux
fenêtres temporelles"] LAC["Data Lake Storage
zones brute, affinée, exposée"] TRF["Transformation
flux de données ou Spark"] ENT["Entrepôt analytique"] RST["Rapports, API, alertes"] A1 --> ING A2 --> ING A3 --> FLX ING --> LAC FLX --> ASA ASA --> LAC ASA --> RST LAC --> TRF TRF --> ENT ENT --> RST classDef src fill:#ede9e1,stroke:#8a4d16,color:#1a1a1a classDef mid fill:#d89253,stroke:#8a4d16,color:#1a1a1a classDef out fill:#1f2428,stroke:#b5651d,color:#f5f2ec class A1,A2,A3 src class ING,FLX,ASA,LAC,TRF mid class ENT,RST out
Le flux ne remplace pas le lot. Dans la quasi-totalité des systèmes sérieux, les deux régimes coexistent et alimentent le même socle analytique.
Le lot : Azure Data Factory
Le service qui compile les bordereaux de la journée a une tournée, des camions et des horaires. Il ne décide de rien, il exécute un plan.
Azure Data Factory tient ce rôle. C'est un orchestrateur : il déplace de la donnée d'un point A vers un point B, appelle des traitements, et gère l'ordre, les dépendances et les reprises. Il ne stocke rien lui-même.
Son vocabulaire tient en cinq objets, et les confondre coûte des heures de débogage.
Le service lié est la connexion : une chaîne de connexion, une identité, un point de terminaison. Le jeu de données est la forme de ce qu'on lit ou écrit à travers cette connexion : un dossier, une table, un format de fichier. L'activité est l'unité de travail, copie de données, appel d'un notebook, boucle, condition. Le pipeline regroupe des activités liées par des dépendances de succès, d'échec ou d'achèvement. Le déclencheur décide quand tout cela démarre.
Où le code s'exécute vraiment
Le point qui surprend le plus en conception : le pipeline est une définition, pas un moteur. L'exécution appartient au runtime d'intégration, et son choix détermine ce que la chaîne peut atteindre sur le réseau.
| Runtime d'intégration | Où il s'exécute | Ce qu'il débloque |
|---|---|---|
| Azure | infrastructure gérée par le service | sources accessibles publiquement, ou via un réseau virtuel géré |
| Auto-hébergé | une machine que tu installes et exploites | atteindre un serveur du réseau interne sans l'exposer |
| Azure-SSIS | nœuds gérés dédiés | exécuter des paquets SSIS existants sans les réécrire |
Le runtime auto-hébergé est la réponse standard à la question « comment lire une base qui n'est pas sur Internet ». C'est aussi une machine à exploiter, à mettre à jour et à redonder, ce que les projets découvrent en général après la mise en production.
Déclencher, et surtout rejouer
Quatre familles de déclencheurs : la planification classique, le dépôt d'un fichier dans un compte de stockage, un événement personnalisé, et la fenêtre bascule. Cette dernière demande qu'on s'y arrête, parce qu'elle est la seule à traiter le temps comme une donnée de premier rang.
Une fenêtre bascule découpe le temps en tranches fixes et contiguës. Chaque exécution est associée à une tranche, connaît ses bornes, peut dépendre de la tranche précédente, et peut être rejouée seule si elle échoue. C'est ce qui rend le rattrapage possible sans script maison.
{
"name": "declencheur-fenetre-horaire",
"properties": {
"type": "TumblingWindowTrigger",
"typeProperties": {
"frequency": "Hour",
"interval": 1,
"startTime": "2026-01-01T00:00:00Z",
"delay": "00:10:00",
"maxConcurrency": 4,
"retryPolicy": { "count": 3, "intervalInSeconds": 300 }
},
"pipeline": {
"pipelineReference": {
"referenceName": "chargement-manifestes",
"type": "PipelineReference"
}
}
}
}
Le delay accorde dix minutes aux données de la tranche pour arriver avant de lancer le traitement. Le maxConcurrency borne le nombre de tranches rejouées en parallèle lors d'un rattrapage, faute de quoi un rattrapage de trois jours sature la source qu'il interroge.
Transformer dans l'outil ou à côté
Deux écoles, et le choix engage l'équipe pour des années.
| Flux de données de mappage | Appel à un moteur externe | |
|---|---|---|
| Écriture | interface visuelle, sans code | notebooks, SQL, code Spark |
| Exécution | grappe Spark gérée par le service | grappe Databricks, pool Spark, moteur SQL |
| Versionnage | définition JSON du flux | code source, comme le reste de l'application |
| Tests | limités à l'aperçu de données | tests unitaires possibles sur la logique |
| Bon cas | transformations tabulaires standard | logique métier, bibliothèques partagées |
| Limite | débogage pénible quand la logique grossit | une compétence de plus à tenir |
Le flux de mappage démarre une grappe Spark à chaque exécution, ce qui introduit un délai d'allumage. Le réglage de durée de vie du runtime garde la grappe tiède entre deux exécutions rapprochées, au prix d'une facturation qui continue de courir.
Un pipeline d'intégration est du code. S'il ne vit pas dans un dépôt, s'il ne se relit pas en revue et s'il ne se rejoue pas sur une tranche isolée, il redeviendra un script personnel que personne n'ose toucher.
Le flux : Event Hubs et le traitement en fenêtres
La balise du conteneur n'attend pas la nuit. Elle émet, en continu, et le port doit absorber ce débit sans jamais dire non.
Event Hubs est le point d'entrée conçu pour ça : un journal ordonné, à haut débit, où les producteurs écrivent et où les consommateurs lisent à leur rythme. Il expose aussi un point de terminaison compatible avec le protocole Kafka, ce qui évite de réécrire un producteur existant.
Deux notions structurent tout le reste.
La partition est une sous-file ordonnée. L'ordre est garanti à l'intérieur d'une partition, jamais entre partitions. Le nombre de partitions décide du parallélisme maximal côté consommation, il se choisit à la création, et selon le niveau de service il se modifie mal ou pas du tout. Une augmentation ne redistribue jamais les données déjà écrites.
Le groupe de consommateurs est une vue indépendante sur le même flux, avec sa propre progression de lecture. Deux traitements qui n'ont rien à voir peuvent lire les mêmes événements sans se gêner ni se les voler.
balises de conteneurs"] subgraph EH["Event Hub"] P0["Partition 0"] P1["Partition 1"] P2["Partition 2"] end P --> P0 P --> P1 P --> P2 P0 --> G1["Groupe temps réel"] P1 --> G1 P2 --> G1 P0 --> G2["Groupe archivage"] P1 --> G2 P2 --> G2 G1 --> ASA["Traitement de flux
agrégats et alertes"] G2 --> LAC["Écriture continue
dans le lac"] classDef prod fill:#ede9e1,stroke:#8a4d16,color:#1a1a1a classDef part fill:#d89253,stroke:#8a4d16,color:#1a1a1a classDef cons fill:#1f2428,stroke:#b5651d,color:#f5f2ec class P prod class P0,P1,P2 part class G1,G2 cons class ASA,LAC cons
Il faut connaître la fonction de capture d'Event Hubs avant d'écrire le moindre consommateur : le service sait déverser lui-même le flux dans un compte de stockage ou dans un lac, par tranche de temps ou de taille. C'est le pont entre les deux régimes, sans une ligne de code.
Les fenêtres temporelles
Un flux n'a ni début ni fin. Pour en tirer un chiffre, il faut découper le temps, et Stream Analytics le fait avec un langage proche du SQL.
SELECT
terminal,
System.Timestamp() AS fin_de_fenetre,
COUNT(*) AS mesures,
AVG(temperature) AS temperature_moyenne
INTO alertes_frigorifiques
FROM mesures_conteneurs TIMESTAMP BY heure_mesure
GROUP BY terminal, TumblingWindow(minute, 5)
HAVING AVG(temperature) > 8
| Fenêtre | Comportement | Ce qu'elle répond |
|---|---|---|
| Bascule | tranches fixes, sans recouvrement | combien de mesures entre 9 h 00 et 9 h 05 |
| Sautante | tranches fixes qui se recouvrent | la moyenne des cinq dernières minutes, rafraîchie chaque minute |
| Glissante | recalcul à chaque entrée ou sortie d'événement | à quel instant précis le seuil a été franchi |
| Session | regroupe tant que les événements s'enchaînent | combien de temps a duré la manœuvre |
| Instantané | événements portant le même horodatage | ce qui s'est produit exactement au même moment |
L'heure de l'événement contre l'heure d'arrivée
C'est le sujet qui sépare une chaîne de flux qui marche d'une chaîne qui ment.
L'heure d'arrivée est celle où le service reçoit le message. L'heure de l'événement est celle où le fait s'est produit. Une balise dans une zone sans couverture réseau garde ses mesures et les envoie toutes ensemble vingt minutes plus tard : les deux horloges divergent, et la moyenne de la fenêtre de 9 h 00 se retrouve calculée avec des mesures de 8 h 40.
La clause TIMESTAMP BY bascule le moteur sur l'heure de l'événement. À partir de là, deux réglages deviennent des décisions de conception : la tolérance au désordre, qui fait attendre le moteur avant de fermer une fenêtre, et la tolérance à l'arrivée tardive, qui décide du sort d'un événement qui débarque après la fermeture. Ignorer ou recaler, il faut choisir, et le choix a des conséquences comptables.
Sans horodatage applicatif, un traitement de flux mesure la santé du réseau, pas celle du terrain.
Le socle analytique : lac, entrepôt, moteur
Sur le terminal, la marchandise ne va pas directement du portique au camion du client. Elle passe par le terre-plein, où tout est posé en vrac mais tracé, puis par l'entrepôt, où elle est triée, contrôlée et prête à sortir.
Le lac de données est le terre-plein. Data Lake Storage est un compte de stockage dont l'espace de noms hiérarchique est activé : les dossiers deviennent de vrais dossiers, le renommage est atomique, et les droits s'appliquent par répertoire. Cette option se décide à la création du compte, pas après.
L'organisation en zones est ce qui distingue un lac d'un dépotoir. Trois zones suffisent, nommées brut, affiné et exposé, ou bronze, argent et or selon le vocabulaire de l'équipe.
conteneur : lac
/brut/manifestes/date_ingestion=2026-08-25/part-0001.json
/affine/manifestes/date_operation=2026-08-25/part-0001.parquet
/expose/trafic_mensuel/annee=2026/mois=08/part-0001.parquet
La zone brute conserve la donnée telle qu'elle est arrivée, sans correction, parce que c'est la seule façon de rejouer un traitement quand on découvre un bogue trois mois plus tard. La zone affinée porte le typage, la déduplication et la qualité. La zone exposée porte les tables agrégées que les rapports interrogent.
Le partitionnement par date dans le chemin n'est pas cosmétique : c'est ce qui permet à un moteur de requête de ne lire que les fichiers utiles. Combiné à un format en colonnes comme Parquet, il divise le volume lu par un facteur qui se compte en dizaines.
Les moteurs qui lisent ce lac
| Data Lake Storage | Pool SQL serverless | Pool SQL dédié | Spark | |
|---|---|---|---|---|
| Nature | stockage de fichiers | moteur de requête sans stockage propre | entrepôt massivement parallèle | moteur de calcul distribué |
| Facturation | volume stocké | volume de données parcouru | capacité provisionnée | durée et taille de la grappe |
| Bon cas | tout poser, à moindre coût | explorer, servir des vues sur des fichiers | requêtes analytiques répétées et concurrentes | transformations lourdes, code, apprentissage |
| Décision structurante | zones et format de fichier | aucune, c'est son intérêt | la clé de distribution des tables | dimensionnement et durée de vie |
| Piège classique | le lac sans convention de nommage | requête qui balaie tout le lac | table mal distribuée, donc mouvements de données | grappe laissée allumée |
Synapse Analytics regroupe ces moteurs dans un espace de travail unique, avec un moteur de pipelines identique à celui de Data Factory. Le pool SQL dédié y répartit chaque table sur un ensemble fixe de distributions, selon un mode par hachage, par tourniquet ou par réplication. Le choix se raisonne exactement comme la clé de partition d'un magasin non relationnel : mal distribuée, une table oblige le moteur à déplacer des données à chaque jointure.
Azure Databricks joue dans la même cour côté Spark, avec un écosystème orienté ingénierie logicielle et science des données. Le choix entre les deux se fait plus souvent sur les compétences déjà présentes dans l'équipe que sur une différence technique décisive.
Reste Microsoft Fabric, qui rassemble ces capacités dans une offre en logiciel de service, facturée à la capacité, avec un stockage unique partagé par tous ses composants. Sur un projet neuf, la question mérite d'être posée dès le cadrage, en vérifiant l'état des annonces au moment où tu conçois : les frontières entre ces produits bougent vite.
Le lac ne coûte presque rien et ne rend presque aucun service tant que personne n'a écrit la convention de zones, de formats et de partitionnement. Cette page de documentation vaut plus que le choix du moteur.
Lot ou flux : ce qui tranche vraiment
L'exploitant du port ne se demande pas si le temps réel est mieux que le rapport de nuit. Il se demande combien de temps il peut attendre avant qu'une information devienne inutile.
| Critère | Le lot s'impose quand | Le flux s'impose quand |
|---|---|---|
| Latence admissible | l'heure ou la journée | la seconde ou la minute |
| Volume par exécution | important, groupé | faible, continu |
| Déclenchement | planifié, ou sur dépôt de fichier | ininterrompu |
| Transformation | jointures larges, historique complet | agrégats sur fenêtre, filtrage, enrichissement |
| Reprise après incident | rejouer la tranche, c'est prévu par l'outil | dépend de la rétention et du décalage conservé |
| Profil de coût | proportionnel au temps d'exécution | proportionnel au débit réservé, y compris la nuit |
| Compétence dominante | modélisation et ordonnancement | temps de l'événement et gestion du désordre |
Deux pièges reviennent systématiquement.
Le premier consiste à choisir le flux pour un besoin dont la latence admissible se compte en heures. On paie alors un débit réservé en permanence, on hérite de la complexité du temps de l'événement, et le rapport sort quand même à huit heures du matin parce que c'est l'humain qui le lit qui arrive à ce moment-là.
Le second consiste à simuler le temps réel avec un lot toutes les cinq minutes. Chaque exécution paie son démarrage, les fenêtres se chevauchent mal, et la reprise devient un casse-tête. Au-delà d'une certaine fréquence, le lot déguisé coûte plus cher que le flux assumé.
La bonne question n'est pas « à quelle vitesse peut-on aller », c'est « à partir de quel retard cette donnée cesse-t-elle de servir à une décision ».
Quatre façons de casser une chaîne d'intégration
Un poste de garde qui note les entrées sur un cahier tient très bien, jusqu'au jour où le cahier est plein et où le garde continue d'écrire sur la couverture.
Le tableur comme format de transfert. Il s'installe parce qu'il marche tout de suite et que tout le monde sait l'ouvrir. Il apporte avec lui des limites de lignes, des conversions automatiques de types, des dates réinterprétées et des identifiants transformés en notation scientifique. Aucune de ces transformations ne lève d'erreur. Elles corrompent en silence.
Le pipeline sans schéma déclaré. Quand la structure attendue n'est écrite nulle part, une colonne renommée à la source produit une colonne vide en sortie, jamais un échec. Déclarer le schéma et faire échouer le traitement en cas d'écart transforme un problème silencieux en incident visible, ce qui est exactement le but.
L'absence de reprise sur échec partiel. Un chargement qui traite dix mille lignes et s'arrête à la sept millième doit pouvoir être relancé sans créer sept mille doublons. Cela suppose une notion de tranche, une écriture idempotente et un point de reprise. Ces trois éléments se conçoivent au premier jour, pas pendant l'astreinte.
Aucun contrôle de fraîcheur ni de volume. Un pipeline vert qui charge zéro ligne reste vert. Une alerte sur l'ancienneté de la dernière écriture, et une autre sur un volume qui s'écarte trop de la normale, coûtent une heure à mettre en place et détectent la majorité des pannes réelles. C'est le prolongement direct de la supervision posée en début de série.
Une chaîne d'intégration ne tombe presque jamais en panne bruyamment. Elle continue de tourner en produisant des chiffres faux, et c'est un humain qui finit par s'en apercevoir.
Scénario B : les résultats de tests perdus dans un tableur
En octobre 2020, l'agence sanitaire britannique Public Health England a reconnu publiquement qu'environ 15 800 résultats de tests positifs au covid n'avaient pas été transmis au dispositif de suivi des contacts pendant environ une semaine.
Aucune intrusion, aucune panne matérielle, aucun serveur tombé. Les laboratoires transmettaient leurs résultats sous forme de fichiers, ces fichiers étaient consolidés dans un modèle de tableur, et ce modèle utilisait le format historique du tableur, dont le nombre maximal de lignes est de 65 536. Chaque cas occupait plusieurs lignes. Une fois la limite atteinte, les enregistrements suivants n'étaient tout simplement pas repris.
Le point décisif tient dans un mot : silencieusement. Le fichier ne signalait rien. Le traitement se terminait normalement. Les tableaux de bord affichaient des chiffres cohérents, simplement incomplets. La conséquence n'était pas informatique : des dizaines de milliers de contacts n'ont pas été appelés dans les délais prévus, à un moment où c'était l'objet même du dispositif.
L'agence a publié sa propre déclaration le 5 octobre 2020 : elle parle de fichiers de résultats ayant dépassé la taille maximale acceptée par le processus de chargement. C'est la couverture de la BBC, le même jour, qui a établi le format de tableur en cause et sa limite de lignes.
Cette chaîne coche trois des quatre défauts listés plus haut. Un tableur comme format de transfert. Aucun schéma déclaré ni contrôle de complétude entre l'entrée et la sortie. Aucune surveillance du volume, alors qu'une simple comparaison entre le nombre de lignes reçues et le nombre de lignes chargées aurait levé l'alerte le premier jour.
Ce n'est pas un cas exotique. C'est la chaîne d'intégration par défaut de beaucoup d'organisations, celle qui a démarré comme un dépannage et que personne n'a jamais requalifiée en système de production.
Le format de transfert est une décision d'architecture. Quand il est choisi par commodité, ses limites deviennent celles du système entier, et personne ne les a lues.
Points clés
- La chaîne se découpe en ingestion, stockage, transformation, restitution. Le lot et le flux ne sont pas deux outils, ce sont deux régimes qui traversent ces quatre étapes et qui coexistent presque toujours.
- Data Factory orchestre sans rien stocker. Le runtime d'intégration décide de ce que la chaîne peut atteindre sur le réseau, et le déclencheur de fenêtre bascule est ce qui rend le rattrapage possible sans script maison.
- En flux, deux notions commandent tout : la partition, qui borne l'ordre et le parallélisme et se fige tôt, et l'heure de l'événement, sans laquelle les agrégats mesurent la latence du réseau plutôt que la réalité du terrain.
- Le lac ne vaut que par ses conventions : zones brute, affinée et exposée, format en colonnes, partitionnement par date. Le moteur de requête se choisit après, selon le profil de lecture et les compétences de l'équipe.
- Une chaîne d'intégration tombe en silence. Schéma déclaré, écriture idempotente, point de reprise et alerte sur la fraîcheur et le volume valent plus cher que le choix du produit.
Dans la série
Palier 2 : Construire les terminaux. Domaine : Stockage & données.
- Précédent : Cosmos DB : partitionnement, unités de requête et cohérence
- Suivant : Réseau virtuel : adressage, appairage et connectivité hybride
- Vue d'ensemble : Concevoir sur Azure : par où commencer
Pour aller plus loin
- Comptes de stockage : redondance, niveaux d'accès, cycle de vie, parce qu'un lac est d'abord un compte de stockage et hérite de toutes ses décisions.
- Infrastructure applicative : messagerie, passerelle d'API et cache, pour la comparaison complète entre les services de messagerie et d'événements.
- Introduction à Azure Data Factory et les runtimes d'intégration.
- Azure Stream Analytics et les fonctions de fenêtrage.
- La capture Event Hubs, le pont sans code entre le flux et le lac.
- La distribution des tables d'un pool SQL dédié, pour comprendre pourquoi une table mal distribuée coûte si cher.
- La déclaration de Public Health England du 5 octobre 2020 et l'article de la BBC sur le format de fichier en cause, les deux sources du scénario B.