Définition et cycle de vie de l’ingénierie de la donnée
Un utilisateur lance un morceau sur Spotify. En quelques millisecondes, l’application produit un événement. Cet événement peut être incomplet, arriver en retard ou être reçu plusieurs fois. Pour alimenter une recommandation, une analyse ou un modèle, il doit accumuler des garanties jusqu’à devenir identifiable, traçable, rejouable, interprétable, exploitable puis consommable.
Cette partie définit le métier, pose le cycle, puis le parcourt sur cet événement, du téléphone jusqu’à la recommandation.
Qu’est-ce que l’ingénierie des données ?
Définition
L’ingénierie des données est le développement, la mise en œuvre et la maintenance de systèmes et de processus qui prennent des données brutes et produisent des informations de haute qualité et cohérentes, destinées aux usages en aval tels que l’analyse et l’apprentissage automatique. Elle se situe à l’intersection de la sécurité, de la gestion des données, du DataOps, de l’architecture des données, de l’orchestration et de l’ingénierie logicielle.
Cette définition met en évidence trois dimensions du métier. Il s’agit de concevoir des systèmes, et non uniquement d’écrire des scripts. Il s’agit aussi d’exploiter et maintenir ces systèmes, car les sources, les besoins et les volumes évoluent. Il s’agit enfin de produire des données utilisables, donc fiables, documentées et adaptées à leurs consommateurs.
Le cycle de vie de l’ingénierie des données
Ces trois dimensions (concevoir, produire et exploiter) s’articulent selon un cycle continu. Reis et Housley y décrivent cinq activités : Génération, Stockage, Ingestion, Transformation et Mise à disposition. Ce cycle a pour entrée la donnée brute, née dans les systèmes sources à l’étape de génération, et pour sortie un produit utilisable, mis à disposition pour l’analytique et la BI, l’apprentissage automatique, les applications d’IA et les applications métier. Le stockage, lui, n’est pas une étape parmi d’autres : c’est un socle transversal et une décision d’architecture. Il détermine sous quel format la donnée est écrite, combien de temps on la garde, ce que cela coûte, ce qu’ingestion, transformation et mise à disposition pourront en faire, et également les usages en aval (Reis et Housley, 2022, chap. 2).
Six exigences permanentes pèsent sur chaque étape :
| Discipline | Ce qu’elle impose |
|---|---|
| Sécurité | Moindre privilège, chiffrement |
| Gestion des données | Qualité, métadonnées, lignage |
| DataOps | Observer et améliorer les pipelines comme on le fait pour le logiciel |
| Architecture | Choix cohérents avec le coût et les usages |
| Orchestration | Ordonner, reprendre, alerter |
| Ingénierie logicielle | Code versionné, testé, idempotent |
Cas pédagogique : suivre l’événement play
Reprenons ce cycle sur un cas concret, fil rouge du reste du chapitre. Un utilisateur lance un morceau depuis l’application mobile ; l’ordinateur est une variante du même type de client, et les deux émettent vers une file. L’objectif est de transformer cet événement brut en donnée utilisable pour la recommandation, l’entraînement de modèles ou l’analyse du comportement utilisateur. L’événement play ci-dessous porte ce fil rouge : il gardera toujours event_id: evt_01J4C3F9, schema_version: 1 et les mêmes champs de base. ms_played: 42180 signifie 42,18 s d’écoute.
{
"event_id": "evt_01J4C3F9",
"schema_version": 1,
"event_type": "play",
"user_id": "u_48291",
"track_id": "t_99821",
"event_time": "2024-01-15T09:23:17Z",
"ms_played": 42180,
"device": "mobile",
"play_context": "playlist",
"country": "FR"
}Un autre type d’événement peut avoir des champs supplémentaires. Il ne remplace pas le play précédent : il illustre seulement la variation de schéma selon event_type.
{
"event_id": "evt_01J4C3G2",
"schema_version": 1,
"event_type": "track_like",
"user_id": "u_48291",
"track_id": "t_11203",
"event_time": "2024-01-15T09:25:42Z",
"device": "mobile",
"play_context": "playlist",
"country": "FR",
"artist": "Daft Punk"
}Le champ artist est propre au track_like. Le contrat conserve néanmoins ses champs de base ; le schéma varie donc selon le type d’événement, comme souvent pour des événements semi-structurés.
À l’échelle d’une grande plateforme, on manipule de l’ordre de milliers de types d’événements et de nombreuses chaînes de traitement. La figure ci-dessous n’en retient qu’un seul fil, celui de notre play. Le scénario s’inspire de technologies publiquement documentées chez Spotify, mais reste une simplification pédagogique, et non une reproduction interne.
Les technologies sont données à titre d’exemple. Le point important est la succession des responsabilités. Sources d’architecture : Spotify Engineering (2019) et Spotify Engineering (2024).
Étape 1 : génération
La donnée naît hors de l’ingénierie, dans les applications, les bases transactionnelles, les capteurs IoT ou les API tierces. L’ingénieur consomme ces systèmes sources. Il ne les possède en général pas. Il doit pourtant en connaître le rythme et la forme, car la moindre évolution du système source peut casser les pipelines en aval.
Deux profils de génération sont courants. Une base applicative impose souvent un schéma à l’écriture. On l’extrait ensuite par snapshot, incrémental ou CDC (Change Data Capture). Des clients applicatifs publient au contraire des événements semi-structurés dans une file. Spotify relève de ce second profil.
Considérations importantes
- À quel rythme les données sont-elles générées et extraites : événements par seconde, gigaoctets par heure, batch ou flux continu ?
- Quelle est leur structure et comment le schéma peut-il évoluer ?
- Faut-il prévoir des doublons, des valeurs manquantes, des erreurs ou des retards ?
- Plusieurs tables ou systèmes doivent-ils être joints pour obtenir une vue complète ?
- Quelles données personnelles sont réellement nécessaires ?
État de la donnée. Le même play est encore un JSON isolé. Les identifiants restent opaques, sans artiste ni genre ; ms_played: 42180 correspond toujours à 42,18 s.
{
"event_id": "evt_01J4C3F9",
"schema_version": 1,
"event_type": "play",
"user_id": "u_48291",
"track_id": "t_99821",
"event_time": "2024-01-15T09:23:17Z",
"ms_played": 42180,
"device": "mobile",
"play_context": "playlist",
"country": "FR"
}Étape 2 : stockage
Le stockage vient juste après la génération : on choisit où la donnée pourra vivre, être conservée et relue. Dans le parcours de notre play, la file d’ingestion (Pub/Sub) le reçoit d’abord, puis la zone brute le conserve (GCS) ; c’est pourquoi la discussion du stockage précède celle de l’ingestion.
Le stockage n’est pas une parenthèse. Il accueille le brut, les tables transformées et parfois le serving. Ce choix conditionne les formats, la rétention, les coûts et la gouvernance.
Deux familles coexistent souvent :
| Data lake (ex. Cloud Storage) | Data warehouse (ex. BigQuery) |
|---|---|
| Stockage objet | Stockage table |
| Événements et fichiers bruts | Tables analytiques |
| Formats Parquet, Avro, ORC… | Requêtes SQL rapides |
| Schéma à la lecture (schema-on-read) | Schéma imposé à l’écriture (schema-on-write) |
| Historique long, peu cher | Serving BI / features / modèles |
Le lakehouse vise les deux : stockage objet et couche table. On le reprend dans ETL/ELT et architectures de stockage.
Considérations importantes
- Les données ont-elles besoin d’un stockage sans schéma imposé, d’un schéma flexible ou d’un schéma strict ?
- Le système supporte-t-il les volumes et les vitesses de lecture et d’écriture attendus ?
- Quels formats, partitionnements et durées de conservation faut-il choisir ?
- À quelle fréquence les données seront-elles consultées et quel en sera le coût ?
- Dans quelles régions peuvent-elles être stockées pour respecter le RGPD et les règles de souveraineté ?
- Quels droits d’accès, mécanismes de chiffrement et outils de catalogage faut-il prévoir ?
Dans notre flux, le play est conservé en zone brute dans un bucket Google Cloud Storage, tel qu’il est arrivé. On n’écrase pas ce brut : il sert de base de replay.
État de la donnée. le play n’a pas encore acquis une nouvelle garantie. On définit l’adresse où il sera conservé après sa réception, avec un partitionnement par heure :
gs://spotify-events-raw/year=2024/month=01/day=15/hour=09/events_20240115T09.jsonl
Étape 3 : ingestion
L’ingestion fait circuler la donnée depuis les sources vers la plateforme. Dans le flux physique, notre play passe des clients à Pub/Sub, puis vers la zone brute GCS ; le traitement et les tables viennent ensuite. Cette frontière est sensible, car la source productrice et la plateforme peuvent évoluer ou tomber en panne indépendamment.
Considérations importantes
- Quels usages justifient l’ingestion et quelle fraîcheur exigent-ils : batch, streaming ou mode hybride ?
- Les systèmes sources et les outils d’ingestion sont-ils suffisamment fiables et disponibles ?
- Dans quel format les données arrivent-elles et quelle est leur destination finale ?
- Les événements peuvent-ils être en retard, en double ou dans le désordre ?
- Comment reprendre après une panne, rejouer une période et isoler les messages invalides ?
- Quels indicateurs permettront de surveiller le débit, la latence et les erreurs ?
Presque toute donnée naît en continu. Le traitement batch n’est qu’une façon de regrouper ces événements, par exemple une journée ou un fichier. Le streaming les traite au fil de l’arrivée. En production, le mode est souvent hybride. On ne passe au streaming que si l’usage métier exige réellement cette rapidité.
| Batch | Streaming | |
|---|---|---|
| Fraîcheur | minutes à un jour | ms à secondes |
| Déclenchement | planning (Airflow, CRON) | événement (Pub/Sub, Kafka) |
| Coût | pic, puis arrêt | infra continue |
| Complexité | faible : job borné | élevée : état et ordre |
Trois sens de transfert se distinguent. La source écrit vers la cible (push), on va chercher les données (pull), ou l’on interroge à intervalle fixe jusqu’à obtenir du nouveau (poll, une variante du pull). Le pull protège souvent la source transactionnelle. Le push convient mieux aux événements.
| Stratégie | Principe |
|---|---|
| Full load | On recharge toute la table à chaque passage |
| Incremental | On n’ajoute que les nouveautés depuis le dernier run |
| CDC | On lit les changements dans les journaux de la base source |
On transforme avant le chargement (ETL) ou après (ELT). Dans de nombreuses plateformes cloud analytiques, l’ELT est privilégié lorsque la destination dispose d’une capacité de calcul adaptée. On le reprend dans ETL/ELT et architectures de stockage.
Un pipeline solide en production repose sur trois exigences : résilience (reprise après un échec), idempotence (deux exécutions produisent le même résultat qu’une seule), backfill (rejouer une période passée après une correction).
Même événement, même retry. À gauche, chaque run insère. À droite, l'upsert sur
event_id remplace.
L’idempotence repose ici sur event_id. Une clé comme (user_id, track_id, timestamp) serait insuffisante : deux écoutes légitimes du même morceau à la même seconde, ou un like et un play, ne sont pas le même événement.
Dans notre cas, le play part des clients vers Pub/Sub, puis vers la zone brute. Trois horloges le suivent. event time est l’heure enregistrée par le client (09:23:17), ingestion time l’heure de réception par la plateforme (09:23:52), et processing time l’heure où un traitement le prend en charge. Le premier répond à une question métier, le deuxième mesure la livraison et le troisième permet d’observer l’exécution du pipeline.
Deux indicateurs simples décrivent déjà la livraison : la proportion d’événements livrés dans le délai attendu et la proportion d’événements publiés effectivement reçus. La plateforme répond de cette livraison ; l’équipe productrice répond de la validité métier du contenu.
État de la donnée. Pub/Sub reçoit d’abord le play : il devient traçable grâce à sa provenance et à son ingestion_time. Lorsqu’il est persisté avec son payload et ses métadonnées dans la zone brute GCS, il devient Bronze et rejouable.
event_id |
schema_version |
device |
play_context |
event_time |
ingestion_time |
processing_time |
|---|---|---|---|---|---|---|
evt_01J4C3F9 |
1 |
mobile |
playlist |
09:23:17 |
09:23:52 |
09:24:03 |
Étape 4 : transformation
Stockée et tracée, la donnée reste muette : t_99821 ne dit rien. La transformation nettoie, enrichit et restructure pour l’analyse, le reporting ou le ML.
L’architecture medallion nomme des états de confiance : Bronze, Silver et Gold, souvent dans le même lakehouse. Ce ne sont ni trois outils ni trois produits GCP. Dans notre exemple, GCS héberge souvent le Bronze, Dataflow écrit le Silver et BigQuery sert souvent le Gold. D’autres organisations parlent de raw, staging, core et marts. Bronze sert surtout au replay et à l’audit, Silver aux analyses détaillées et au ML, Gold à un usage métier défini.
Bronze. C’est le même événement tel que reçu, encore opaque : t_99821 ne dit rien. Il est rejouable, dans les limites de la rétention.
{
"event_id": "evt_01J4C3F9",
"schema_version": 1,
"event_type": "play",
"user_id": "u_48291",
"track_id": "t_99821",
"event_time": "2024-01-15T09:23:17Z",
"ms_played": 42180,
"device": "mobile",
"play_context": "playlist",
"country": "FR"
}gs://spotify-events-raw/year=2024/month=01/day=15/hour=09/events_20240115T09.jsonl
Silver. L’événement est nettoyé, dédupliqué et enrichi par le référentiel. Le grain reste celui du play : il est devenu interprétable. t_99821 est Planet Caravan de Black Sabbath ; ms_played: 42180 correspond à 42,18 s écoutées.
event_id |
user_id |
track_name |
artist_name |
genre |
duration_sec |
ms_played |
|---|---|---|---|---|---|---|
evt_01J4C3F9 |
u_48291 |
Planet Caravan | Black Sabbath | heavy metal | 272 | 42 180 |
Gold. On change de granularité : une ligne par utilisateur et par artiste, plus par événement. Après une semaine, notre play a contribué, avec treize autres écoutes, à un agrégat exploitable. L’event_id n’appartient plus à cette granularité ; le lignage doit rester retrouvable. Ce n’est pas encore un produit de données.
user_id |
Artiste | stream_count |
affinity_score fictif |
|---|---|---|---|
u_48291 |
Black Sabbath | 14 | 13,2 |
Le score 13,2 est fictif : par exemple, affinity_score = 0,8 × stream_count + 2, donc 0,8 × 14 + 2 = 13,2. Le calcul reste fictif, mais suffisant pour illustrer le concept.
Si track_id est absent ou les doublons non traités, les indicateurs artiste sont faussés. La modélisation (étoile, flocon, SCD) se décide ici ; on la reprend dans Modélisation de données.
Considérations importantes
- Quels usages et quelles décisions métier cette transformation doit-elle servir ?
- Sa valeur métier et son retour sur investissement justifient-ils son coût de calcul et de maintenance ?
- Quelle granularité et quel schéma la table produite doivent-ils avoir ?
- Quelles règles métier faut-il appliquer, par exemple pour définir une écoute valide, un artiste ou un pays ?
- Quels contrôles garantissent l’unicité, la présence et la validité des valeurs ?
- Les transformations sont-elles versionnées, testables et rejouables sur l’historique ?
Une donnée n’est pas fiable simplement parce qu’elle se trouve dans une table Gold. Sa qualité doit être mesurée.
| Contrôle | Objectif |
|---|---|
event_id renseigné |
100 % |
event_id unique |
100 % |
track_id présent dans le catalogue |
au moins 99,9 % |
ms_played positif et plausible |
au moins 99,9 % |
| Événements disponibles en Silver | 99 % en moins de 10 minutes |
Garantie acquise : interprétable et exploitable.
La donnée respecte une granularité, des règles métier et des critères de qualité explicites.
Étape 5 : mise à disposition
Mettre à disposition la donnée consiste à la rendre trouvable, compréhensible et fiable, dans un support adapté à l’usage. Une table techniquement correcte n’est pas encore un produit de données. Elle devient un produit lorsqu’on lui ajoute une finalité, un propriétaire, des consommateurs, des droits et des objectifs mesurables.
Considérations importantes
- Les données reflètent-elles fidèlement la réalité et leur qualité permet-elle une analyse ou un feature engineering fiable ?
- Les critères de qualité ont-ils été définis avec les équipes qui consomment les données ?
- Les analystes et les data scientists peuvent-ils trouver et comprendre rapidement les jeux de données utiles ?
- Chaque produit de données possède-t-il un responsable, une finalité et un contrat clair ?
- Quelles garanties de fraîcheur, quels droits d’accès et quel délai d’annonce faut-il prévoir avant un changement ?
- Qui intervient en cas d’incident et comment l’utilisation des données est-elle suivie ?
Un produit peut alimenter le BI, le ML ou le reverse ETL. Un système RAG est un autre usage aval possible, traité dans le module IA : il se branche après la mise à disposition, sans allonger le cycle lui-même. Dans notre scénario, une erreur laissée en Silver peut se propager jusqu’à une recommandation.
| Propriété | Valeur |
|---|---|
| Produit | user_artist_affinity |
| Finalité | Alimenter les recommandations |
| Granularité | Une ligne par utilisateur et artiste |
| Propriétaire | Équipe du produit de recommandation |
| Fraîcheur | 99 % des données publiées avant 6 h UTC |
| Qualité | Moins de 0,1 % d’artistes inconnus |
| Classification | Donnée pseudonyme, usage interne |
| Compatibilité | Préavis de 30 jours avant une rupture |
La fraîcheur doit être mesurée concrètement. Par exemple, on peut vérifier que 99 % des données sont publiées avant 6 h, plutôt que de promettre simplement des données « fraîches ».
État de la donnée. La table Gold devient un contrat : propriétaire, fraîcheur, consommateurs (BI, service de recommandation, reverse ETL) et droits. C’est un produit consommable, sans qu’il faille demander à chaque fois « c’est quoi cette table ? ».
Garantie acquise : consommable.
La donnée possède une finalité, un propriétaire, un contrat et des objectifs mesurables.
Un événement, six états
Les cinq étapes décrivent les activités du cycle, avec Storage comme socle. Les six états ci-dessous décrivent les garanties qu’accumule notre unique play ; ce sont deux lectures complémentaires, pas deux listes concurrentes.
La donnée acquiert progressivement des garanties. Cet axe de confiance est indépendant de la fréquence d’accès, des droits accordés et de la classe de stockage.
| État | Garantie principale |
|---|---|
| Généré | Identifiable : identifiant et contrat |
| Reçu | Traçable : arrivée et provenance connues |
| Bronze | Rejouable : payload et métadonnées conservés |
| Silver | Interprétable : typé, dédupliqué et enrichi |
| Gold | Exploitable : grain et question métier définis |
| Produit | Consommable : contrat, propriétaire et objectifs mesurables |
La valeur d’une donnée ne vient pas uniquement de son contenu. Elle vient des garanties accumulées tout au long de son parcours.
- Générer : identifier les sources, leur format et leur fréquence.
- Stocker : choisir une solution adaptée au volume, au coût et à l’usage.
- Ingérer : acheminer les données sans perdre les messages ni créer de doublons.
- Transformer : nettoyer, valider et enrichir les données.
- Exploiter : produire une information utile pour l’analyse, le ML ou le métier.
- Servir : publier une donnée documentée, fiable et facile à consommer.