Skip to content

Commit

Permalink
feat: Article REX plateforme data
Browse files Browse the repository at this point in the history
  • Loading branch information
lepiaf committed Nov 13, 2023
1 parent a5247e2 commit 61d3f59
Show file tree
Hide file tree
Showing 2 changed files with 229 additions and 0 deletions.
229 changes: 229 additions & 0 deletions _articles/fr/2023-10-12-rex-plateforme-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
---
contentType: article
lang: fr
date: '2023-10-11'
slug: retour-experience-construction-plateforme-data
title: "Retour d'expérience sur la construction de la plate-forme data"
excerpt: |
Les besoins en analyse de données sont de plus en plus grandissant. Avec quelques outils, il est possible de faire
des extractions, transformation et visualisation très rapidement. Cependant, pour assurer la pérénité et
l'évolutivité de ces analyse, il est nécessaire de monter une plateforme dédié et d'industrialiser les différents
processus.
authors:
- tthuon
categories:
- architecture
---

## Le contexte

Dans le cadre d'une mission Data Engineer chez un client, j'ai rejoins le pôle “Data Factory” pour analyse et comprendre
le comportement des utilisateurs. Cela permet leur permet de mieux guider l’ajout des fonctionnalités et des produits à
lancer.

Un Poc (Proof of Concept, ou preuve de concept) a été mise en oeuvre par l'équipe data. Elle s'articule autour d'un
pipeline ELT (extract, load, transform) en utilisant les technologies suivantes : Google Cloud Platform, Talend, dbt et
Power BI.

Pour rapidement tester le PoC, le pipeline est exécuté sur Jenkins. Cependant, le détournement de l'usage de Jenkins
pour l'exécution du pipeline n'est pas sans incidence. Jenkins n'est pas adapté pour ce travail : pas de retry, écriture
du pipeline en Groovy, un seul environnement d'exécution.

Comment fiabiliser les traitements et industrialiser le processus de déploiement ?

C'est dans ce context que ma mission commence.

## Le pipeline ELT : Extract, Load, Transform

Comment ce pipeline fonctionne ? Qu'elles sont les étapes ? Qu'elles sont les besoin de ce pipeline ?

Dans son principe de fonctionnement, il va chercher des données dans différentes sources, les charger dans un entrepôt
de données, transformer et créer de nouvelles structure données pour qu'elles soient ensuite affichés.

### Extraction et chargement des données dans Google BigQuery

En sources de données, j'ai :

- MySQL
- MongoDB
- Appel HTTP vers des API externes

Pour la phase d'extraction et chargement dans [Google BigQuery](https://cloud.google.com/bigquery/docs/introduction),
Talend a été mis en place pour effecter ce travail. C'est un outil qui permet de faire des pipeline ETL (Extract,
Transform, Load; à ne pas confondre avec ELT) complète. Ici, il a été utilisé pour faire
uniquement la phase d'extraction et de chargement dans Google BigQuery.

Le développement et la modification nécessite un client lourd et une compilation manuel du pipeline d'extraction.

Une fois que la donnée est dans BigQuery, la phase de transformation peut commencer.

### Transformation avec dbt

Cette transformation est effectuée par [dbt](https://www.getdbt.com/) directement dans l'entrepôt de données Google
BigQuery.

dbt n'exécute rien dans l'entrepôt de données, mais il permet d'organiser la transformation des données et de
templatiser les requêtes SQL. C'est Google BigQuery qui exécute les requêtes SQL.

Durant cette phase de transformation, de nouvelle structure de données sont créés stocker le resultat des calculs. Ces
aggrégats de données sont ensuite affiché par un outil de visualisation de données : Power BI.

### Affichage des données avec Power BI

Le but final de tout ce travail est d'éviter d'effectuer tous les calculs au moment d'afficher les rapports d'analyse.
Sans le travail en amont de calcul et d'aggrégation de données, l'affichage des graphiques seraient très longs.

Ce pipeline est fonctionnel et déjà en place avec Jenkins. Voyons l'architecture de la nouvelle plateforme data.

## Architecture de la plateforme data

Nous avons vu dans la précédente partie le fonctionnement du pipeline ELT dans Jenkins. Le but est de transposer dans
une plateforme plus robuste et adapté à ce type de travail.

Pour cela, nous avons besoin d'un outil pour orchestrer ces différentes étape du pipeline et de les relancer en cas d'
erreur. Apache Airflow est le parfait candidat. Google propose une version géré : Google Composer.

Les pré-requis pour cette nouvelle infrastructure sont les suivantes :

- Utiliser Google Composer
- Utiliser le maximum d'outil géré par Google pour faciliter la maintenance
- Infrastructure as Code avec Terraform
- Des environnements séparés et dédiés pour les tests
- Tout le code nécessaire pour effectuer une tâche est dans une image Docker
- Surveillance et alerte en cas d'échec

Nous avons donc le schéma suivant :

![architecture]({{ site.baseurl }}/assets/2023-10-12-rex-plateforme-data/architecture.png)

Le schéma est assez dense, nous allons le décomposer.

Tout d'abord, il y a une ligne de séparation entre l'infrastructure data et l'infrastructure, dit devops, qui est
propriétaire des bases de données. Cette démarcation se traduit dans le code de l'infrastructure et permet de
bien délimiter les responsabilites entre les équipes.

Nous retrouvons donc en partie supérieure du schéma les sources de données de type base de données qui sont géré par
l'équipe devops e-commerce. Nous ferons des demandes d'accès à ces sources.

Dans la partie inférieure, nous retrouvons toute l'infrastructure data. Il y a de nombreux service géré par Google.

Nous pouvons lister les services suivants :

- Secret Manager
- Artifact Registry
- Composer
- Cloud Storage
- Cloud IAM
- Cloud Logging
- Cloud Monitoring
- BigQuery

Et pour l'environnement de développement spécifiquement, nous avons :

- Cloud SQL
- MongoDB Atlas

Toute l'installation et la configuration de l'infrastructure est effectuée avec Terraform.

## Conditionnement des charges de travails

Une fois que l'infrastructure est configurée avec Terraform, il reste à déployer le pipeline ELT que nous avons décris
précédemment. Il y a deux étapes : Extraction-Chargement, Transformation. La première étape est effectué par Talend, la
seconde par dbt.

Le service Composer utilise Kubernetes pour exécuter Apache Airflow. En quelques mot, [Apache Airflow](https://airflow.apache.org/) est un logiciel libre qui permet d'exécuter et d'ordonnancer des tâches.

Il serait donc intéressant d'exécuter nos travaux dans Kubernetes. Pour cela, nous avons besoin d'une image Docker.

Talend et dbt sont conditionnés dans des images Docker. Il faudra écrire les fichiers Dockerfile et construire les images qui seront stocké dans le service Artifact Registry. Ainsi, à l'aide de l'opérateur [KubernetesPodOperator](https://airflow.apache.org/docs/apache-airflow-providers-cncf-kubernetes/stable/operators.html) fourni par Apache Airflow, les charges de travails Talend et dbt sont exécuté dans Kubernetes.

L'usage des images Docker facilite grandement l'usage d'outil diverse et varié qui ne seraient pas compatible avec l'environnement Composer.

Je n'ai pas rencontré de difficulté particulière, hormis le choix de l'image de base pour Talend. Il [n'existe plus d'image](https://github.com/docker-library/openjdk/issues/505) officiel OpenJDK JRE. J'ai dû chercher et selectionner une image d'une des organisations qui construit une image Docker viable. L'image Docker de base fourni par l'organisation Adoptium me semblait la plus mûre : [https://hub.docker.com/_/eclipse-temurin/](https://hub.docker.com/_/eclipse-temurin/)

## Le pipeline avec un Graph Orienté Acyclique

Talend et dbt sont nos deux principales briques. Il reste à les organiser dans un fichier : un DAG. DAG pour _Directed Acyclic Graph_ ou Graph Orienté Acyclique en français. Pour simplifier, le graph se lit dans un sens, il a un début et une fin, et il n'est pas possible de revenir au début du graph.

```mermaid
flowchart LR
talend[Extraction-Chargement Talend] --> dbt_model[dbt model] --> refresh_power_bi[Mise à jour PowerBI]
```

Ce diagramme va se traduire de cette façon dans un DAG Airflow.

```python
from airflow import models
from airflow.providers.cncf.kubernetes.operators.pod import (
KubernetesPodOperator,
)


with models.DAG(...) as dag:
talend = KubernetesPodOperator(...)
dbt_model = KubernetesPodOperator(...)
refresh_power_bi = KubernetesPodOperator(...)

talend >> dbt_model >> refresh_power_bi
```

On retrouve dans le DAG l'opérateur _KubernetesPodOperator_, et enfin l'ordre des tâches qui seront exécuté par Airflow.

La création du DAG n'est pas complexe en soit. Il y a des petites subtilité à bien comprendre pour maitriser le fonctionnement d'Airflow.

### Date de déclenchement, interval de date de donnée

En plus de la notion de date de déclenchement de traitement, il y a les date d'intervalle de données. Airflow va déclencher un traitement pour une intervalle de date de données antérieur à la date de déclenchement et de la durée de la prochaine date de déclenchement.

Prenons l'exemple suivant, pour un DAG configuré avec `schedule="0 0 * * *"`. Airflow doit déclencher un traitement tous les jours à minuit.

Pour le jour actuel 18 octobre 2023 00h00 UTC
- la date de déclencement : "18 octobre 2023 00h00 UTC"
- la date de début de traitement des données : 17 octobre 2023 00h00 UTC
- la date de fin de traitement des données : 17 octobre 2023 23h59 UTC
- la date de prochain déclenchement : "19 octobre 2023 00h00 UTC"

Pour plus d'information, [https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/dag-run.html#data-interval](https://airflow.apache.org/docs/apache-airflow/stable/core-concepts/dag-run.html#data-interval)

Cette notion n'est pas importante dans notre cas d'usage, mais il l'est lorsque les traitements doivent extraire des données sur un interval de date. Cela permet de ne prendre qu'une partie des données et non l'intégralité. Il est également possible de rejouer des traitements sur une période spécifique.

N'oubliez pas que les dates sont dans le fuseau horaire UTC ! Si votre grappe Composer démarre à minuit au fuseau horaire Europe/Paris (donc 22h00 UTC __la veille__), il va avoir un double traitement : 1 traitement pour l'intervalle de date de donnée de la veille et 1 autre pour l'intervalle de date de données du jour du démarrage du Composer.

### Gérer les resources

Gérer les resources CPU et mémoire ne sont pas évidente. En particulier sur des langages que je ne connaît pas.

De manière générale, plus la charge de travail à de la ressource, plus elle va faire le traitement rapidement. C'est le cas de Talend.

Avec 1 CPU et 4Gio de mémoire, l'exécution était longue. En passant à 4 CPU et 8Gio, ça réduit le temps de moitié. Les graphiques dans Google Monitoring m'ont aidé à faire ce changement et à surveiller l'utilisation des resources.

Dans le DAG, cela se traduit de cette façon

```python
from kubernetes.client import models as k8s_models
from airflow.providers.cncf.kubernetes.operators.pod import (
KubernetesPodOperator,
)

talend = KubernetesPodOperator(
(...)
container_resources=k8s_models.V1ResourceRequirements(
requests={
"cpu": "4",
"memory": "8G",
},
),
)
```

## Sécurisation de la plateforme

## Mise en production

## Surveillance et alerte

## Et la suite ?


## Pour conclure, mon retour d'expérience

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 61d3f59

Please sign in to comment.