Transformation de données avec un outil ETL

talend-logo

Cet article présente un retour d'expérience sur des projets de transformation de base de données avec l'ETL Talend.

Qu'est-ce qu'un ETL ?

Pour Extract, Transform , Load, un ETL est un outil permettant d'extraire les données d'une base, de les transformer pour les charger dans une autre base de données. Le terme base de données est au sens large : fichiers, SGBD, autre.

Talend est un ETL basé sur Eclipse, qui génère des programmes en langage Java.

A savoir

  • Un outil ETL ne préconise pas contre le besoin de maîtrise des SGBD et du SQL.
  • Il faut donc maîtriser les SGBD, le SQL et les composants de l'outil ETL: la surface de compétence requise est donc plus large avec un outil que sans.
  • Il faut disposer d'un environnement complet côté source et cible.
  • Dans le cas d'une centralisation (cf. "Le contexte" ci-dessous), il faut disposer de dumps différents côté source.
  • Si l'environnement cible est en développement en même temps que la migration, bien s'assurer que le travail en mode incrémental est géré au niveau du développement de la migration.

Le contexte

Le contexte d'un projet de transformation de données fait fortement varier sa complexité.

On peut avoir un ratio de 1 à 10 selon les opérations à mener:

  • Passer d'un type de SGBD à un autre (ex. MySQL vers PostgreSQL)
  • Migration simple: copie d'une base et son schéma vers une autre, avec éventuellement création de la base de destination (simple)
  • Centralisation: copie de n bases vers une base, c'est à dire copie, mapping des PK/FK, rapprochement des référentiels (moyen)
  • Intégration: Migration simple ou centralisation, mais avec une transformation du schéma, pour intégrer les données d'une application dans une autre. (complexe)
  • Base de données utilisée à froid: rupture de service pendant la migration (contrairement à un projet décisionnel où l’exécution de la migration se fait applications démarrées)
  • Exécution unique (simple)
  • Exécution incrémentale (complexe)
  • Pas de contrainte de performance 'extrême'.

La spécification

Un fichier Word, en mode révision et versionné, stocké dans la GED du projet, peut accueillir les spécifications d'un projet de transformation de données. Celui-ci doit contenir et bien expliciter le contexte, pour être partagé avec tous les acteurs, prendre en compte toutes les complexités et éviter le rework.

Lors d'une migration, la base de travail correspond aux bases de données sources et cibles. Cependant, le client n'a pas forcément l'expérience de ces derniers. Il connait plutôt les applications sources et cibles. L' essentiel est que les acteurs échangent au même niveau, en particulier pour maîtriser les transformations que les applications appliquent sur les données avant de les présenter ou de les stocker.

La spécification doit contenir les dictionnaires de données sources et cibles. Des noms uniques à tout le dictionnaire doivent être utilisés pour désigner les champs. Ces noms de champs doivent être fonctionnels pour permettre de déterminer leur position dans l'application. Les mappings et leurs règles se baseront sur ces noms. Ainsi on obtient un chemin complet: appli source -> bdd source -> bdd cible -> appli cible.

Chaque acteur, concentré sur un use-case, pourra retrouver les références de son périmètre par recherche exacte.

Les mappings doivent être décris en blocs fonctionnels, de ces derniers découleront les sous(-sous)-modules techniques de la migration.

La conception technique

Un travail sur la conception technique est crucial pour maximiser la souplesse et l'efficacité d'un projet de transformation de données. La conception doit permettre l'efficacité en développement, en test, en recette et en retour de recette. Il n'y a pas forcément de document accueillant cette conception, si la spécification est suffisante. Par contre la conception va permettre de construire un squelette de projet et des règles de développement pour obtenir un projet maîtrisé notamment par l'utilisation de conventions.

Le graphique ci-dessous illustre un projet de migration. 'gO' et un job de "Niveau O", c'est le point de départ du programme: le "main". Ce job de Niveau O est un job d'orchestration: il appelle d'autres jobs.

Ainsi exécuter gO veut dire:

  1. Exécuter gA et gB sans ordre précis (dès le lancement du job car ces deux tâches n'ont pas d'antériorité)
  2. Exécuter gC dès que gA et gB sont terminées.
  3. Exécuter gD dès que gC est terminée.
Schéma 2 de la structuration d'un programme ETL

Schéma 1 : Structuration du contenu d'un job

Le même principe s'applique sur tous les niveaux d'imbrication comme ci dessous. Ci-dessous le contenu de gC est affiché. Notez que préfixer les jobs d'orchestration par 'g' permet uniquement de les distinguer facilement des autres.

Schéma 2 de la structuration d'un programme ETL

Schéma 2: Structuration d'un programme ETL

Un bon nommage est une structuration en arborescence des jobs, par groupes fonctionnels, puis sous-groupes, etc. permettant de localiser très facilement quel élément technique couvre quelle exigence fonctionnelle. C'est aussi une plus-value sur les différentes phases du projet :

  • Développement/Test: Créez de petites unités exécutables indépendamment, pour pouvoir travailler une action sans avoir besoin de ré-exécuter toutes les actions antérieures. Ces unités doivent détruire leur sortie et la recréer afin d'être re-jouable: cela implique qu'elles ne doivent pas modifier leur entrée. Cela est impossible quand il s'agit de faire un update : il faut essayer à tout prix de ne pas faire d'update. Multipliez les colonnes contenant chacune une partie de la concaténation ou du calcul, et ajoutez une action qui agglomère l'ensemble.
  • Recette: Le recetteur pourra avoir à sa disposition l'application source et cible avec un dump cohérent (ou plus directement les accès aux bases si la recette se fait à ce niveau). Si le client recette sur l'application cible, il exprimera ses retours à ce niveau. Le qualifieur des retours devra maîtriser ce contexte.
  • Retour de recette: Chaque unité d’exécution doit être 'reliable' à la spécification facilement par son nom. Les noms peuvent être longs et contenir plusieurs parties, ne pas faire d’abréviation.

 

Le développement

L'utilisation d'une telle structure "rejouable indépendamment" permet au développeur  de tester son job en quelques secondes (au lieu de quelques heures dans un cadre mono-bloc!). Après les jobs d'orchestration, les jobs 'normaux' (cA, cB, etc. du schéma 2) vont quant à eux contenir de 'vraies' tâches à exécuter, de différents types:

  1. Initialisation : Supprimez les vues temporaires de l’exécution précédente
  2. Validation : Vérifiez que les entrants respectent les critères attendus par la migration
  3. Chargement : Extrayez de la base source les données utiles à une transformation et les stocker en base temporaire.
  4. Transformation : Appliquez une règle de gestion sur les données temporaires et stockez les en base temporaire sous leur forme requise par la base cible.
  5. Intégration : Insérez en base cible les lignes de la base temporaire qui sont vouées à cet effet.
  6. Statistique : Créez les vues/fichiers excel qui font le résumé utile à la constatation du résultat de la migration : lignes orphelines anormales lors de jointure ou de rapprochement de référentiels, nombre de lignes crées, etc.

Le job principal d'une migration va appeler des types de job dans l'ordre cité, à priori. Faire toute la validation au plus tôt est préférable, comme faire toute l'intégration à la fin.

Trucs et astuces pour le développeur

  • Chaque job ne doit pas modifier son entrant pour être relancé sans relancer le job maître.
  • Créez de petites unités exécutables indépendamment, pour pouvoir travailler une action sans avoir besoin de ré-exécuter toutes les actions antérieures : pas d'update.
  • Prenez soin du nommage: chaque élément devra être identifié facilement  (lien avec la spec, rôle)
  • Faites une copie des bases temporaires et cibles créées lors d'une livraison. Ceci afin de repartir de ces dernières pour chaque retour de recette étudiée, afin d'être certain que tout job étudié a les mêmes entrants que lors de la livraison.
  • Schéma de la base d'entrée : On peut gérer une variation minime de la structure par paramétrage, pour gérer plus il faut faire deux projets de chargement
  • Dumps source : tentez d'avoir le plus de dumps différents possible pour éviter les erreurs dues à la variabilité imprévue des données (surtout quand les contraintes d'intégrité sont faibles ou lors de traitement de saisie manuelle)
  • Table temporaire : si vous renommez l'une d'elles, pensez bien à supprimer manuellement de la base temp l'ancienne table pour éviter les confusions.
  • Table temporaire : Attention lors de l'évolution d'une table temporaire, mettez à niveau tout de suite les jobs qui se basent dessus.
  • Utilisez la configuration par contexte pour toute valeur
  • Subdivisez les contextes : technique/fonctionnel/spécifique
  • Attention aux valeurs en dur "cachées" : Faites un test complet avec un contexte différent en ayant démonté les bases n'étant pas censées être utilisées.
  • Exécutez un job en cours de confection après maximum 3 composants ajoutés sur celui-ci.
  • Composant tInput : Bien partager les connexions aux bases de données entre les jobs avec la fonction "partager une connexion existante"
  • Composant tInput : N'écrire du code sql que lorsqu'il y a un problème avéré de performance
  • Composant tOutput : chaque job doit posséder ses propres tables temporaires, et doit les supprimer si elles existent afin de permettre la re-jouabilité.
  • Composant tMap : Ne pas mettre plus de deux/trois entrants, pour éviter confusions et debuggings difficiles
  • Composant tMap : Un seul inner join dans un composant tMap
  •  Composant tMap : Créez une table temporaire pour stocker les orphelins lors d'un inner join
  • Composants logCatcher, statCatcher, onComponentError, tDie : créez un job de test dédié à manipuler et comprendre le fonctionnement dans chaque cas de figure
  • Migration de filesystem : le faire dans un job pour une homogénéité du livrable.
  • Migration de filesystem : indiquez les succès/erreurs dans une table temporaire, en indiquant l'objet métier auquel se rattache le fichier.

Conclusion

Cet article a présenté des conseils lors de la mise en œuvre d'un projet de transformation de données avec un outil ETL en l'occurrence Talend. Aussi bons les outils soient-ils, ils ne retirent pas le besoin de maîtriser la technologie sous-adjacente, à savoir SQL et éventuellement Java, en sus de l'outil lui même.

Un autre point à garder à l'esprit est celui du niveau où se place le client, bien souvent applicatif, et celui où se place les développeurs, bien souvent base de données. Cela peut induire des incompréhensions qui seront vite gommées par le support d'une personne maîtrisant l'ensemble de la chaîne (cette maîtrise pouvant à minima s'étaler sur plusieurs personnes).

Pour terminer, une structuration forte par convention en sus de l'architecture de l'outil est le garant du bon fonctionnement du projet.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.