Il est important pour nos clients de savoir qu’ils auront toujours accès à leurs données au moment où ils en ont besoin. Qu’ils souhaitent afficher un dashboard, faire du drill-down ou encore extraire les données via l’API, il faut qu’ils puissent en requêter potentiellement un grand volume de manière performante afin d’atteindre leurs objectifs, et ainsi d’apporter de la valeur à leurs entreprises. 
Dans les coulisses, les ingénieurs d’AT Internet s’affairent à mettre en place des systèmes de traitement et de stockage de la donnée pour rendre ceci possible. Ils utilisent à cet effet les divers outils à leur disposition. 
Cet article est le premier d’une (je l’espère) série dont le but sera de vous présenter certaines des technologies liées au stockage de la donnée que nous utilisons chez AT Internet. Cet article en particulier se concentrera sur Apache Parquet, un format de stockage de fichier conçu pour le big data. 

Cela fait maintenant plusieurs années qu’AT Internet a commencé une grande refonte de sa chaîne de traitement. Certains aspects fondamentaux de cette refonte deviennent dernièrement plus visibles avec des outils tels que Data Query 3 et le nouveau Data Model faisant leurs premiers pas au grand jour. En interne, les premiers blocs de cette transition ont été posés il y a maintenant quelques années quand l’entreprise a commencé à re-concevoir depuis la base sa manière de traiter et stocker la donnée en profitant du potentiel qu’a à offrir l’écosystème Big Data. 
L’une des clés de voûte de cette nouvelle approche est le stockage orienté colonne, qui rend possible la dénormalisation de manière performante. Cet article tentera de vous expliquer de quoi il s’agit et quels bénéfices cela apporte. Mais avant de se lancer dans ces explications, commençons par parler de la manière dont la donnée est stockée traditionnellement, notamment au travers de la normalisation et du stockage orienté ligne

L’approche traditionnelle du stockage de la donnée : la normalisation 

Admettons que l’on souhaite créer une base de données avec un certain nombre d’informations liées à des films. 

Movie Id Movie name Release year Author name Authorcountry 
The Matrix 1999 The Wachowskis USA 
The Matrix Reloaded 2003 The Wachowskis USA 
The Matrix Revolutions 2003 The Wachowskis USA 

Comme vous pouvez le constater, dans le modèle de stockage plus haut, l’information de l’auteur est dupliquée sur chaque film, malgré le fait que dans le cas en question, cette donnée est exactement la même pour chacune des lignes. 
Cet exemple n’est qu’un prototype, un exemple jouet, mais dans le monde réel beaucoup de données se retrouvent ainsi dupliquées / partagées dans les bases de données. On pourrait par exemple vouloir stocker les acteurs ayant joué dans chaque film; ou entrer à un niveau plus profond et stocker des informations à propos des pays de provenance des acteurs ou des réalisateur … ou les deux ! 
On sent intuitivement que le fait de stocker la donnée en la dupliquant peut rapidement se mettre à poser problème si une solution technique n’est pas apportée. 
Traditionnellement, la bonne manière, la manière standard de stocker ce type de données et de séparer les différents types de données dans différentes tables, de manière à réduire, voire éliminer les doublons, et cette technique a pendant longtemps été de facto la façon de procéder dans l’industrie. 

Movie Id Movie name Release year Author id 
The Matrix 1999 
The Matrix Reloaded 2003 
The Matrix Revolutions 2003 
Author id name country 
The Wachowskis USA 

Dans la chaîne de traitement actuelle, celle qui est utilisée pour exécuter vos requêtes Data Query (la vénérable ancienne version), la plupart des données sont stockées de cette manière, qui est appelée une forme normale
Cette approche a l’avantage de réduire la duplication et donc réduire la quantité de données qui doit être stockée. Dans de nombreux cas d’usage, stocker la donnée de cette manière est le plus naturel, le plus écologique et le plus performant car les systèmes de gestion de bases de données (SGBDs) ont des mécanismes permettant de rendre les requêtes sur ce type de schémas efficace. Comment ? A travers des techniques telles que le calcul et le stockage de statistiques internes au moteur de base de données, ou encore l’optimisation des requêtes. 
Dans le monde de l’analytics, où l’on réalise surtout des requêtes de type OLAP, ce paradigme commence à poser quelques problèmes de nos jours avec l’explosion des quantités de données collectées. 
Le plus important de ces problèmes survient quand on essaie de croiser plusieurs tables de tailles importantes. Dans le jargon technique, cela revient à réaliser une opération de jointure entre plusieurs tables. 
Aux échelles de données traitées et requêtées par AT Internet, cette étape de jointure peut être très coûteuse et complexe à réaliser de manière performante. Dans le cas où la requête est mal optimisée par le moteur de SGBD, le coût de traitement peut être tel que celui-ci se traduit in fine par un requêtage trop lent pour le client final. 

Une autre manière de faire les choses : dénormaliser la donnée pour obtenir de la performance au requêtage 

Data Engineer 1 – Pourquoi ne pas juste tout stocker de manière dénormalisée ? De cette manière nous n’aurons pas à payer le prix de ces fichues jointures à chaque fois que le client voudra requêter sa donnée ! 
Data Engineer 2 – Es-tu bien sérieux ? Te rends-tu compte de la duplication que cela engendrerait ? 
Data Engineer 2 – … 
Data Engineer 2 – This is madness ! 
Data Engineer 1 – Madness ? … THIS IS DATA ! 

La justification pour adopter une telle approche est assez simple : éviter d’avoir à réaliser des jointures implique des requêtes plus simples, plus faciles à optimiser, et donc de meilleurs temps de réponse pour l’utilisateur final au moment du requêtage. 
Empiriquement, on remarque que le coût de stockage de la donnée est plus que compensé par les performances de requêtage obtenues, et ceci est d’autant plus vrai que l’on peut déployer un certain nombre d’astuces pour soulager le poids de la redondance. 

Le format colonne 

L’une des manières de compenser les problèmes de la duplication de la donnée en revenant à un stockage dénormalisé est en utilisant ce que l’on appelle un format orienté colonne
Dans une base de données traditionnelle, chaque enregistrement (record en anglais), est stocké d’un bloc. Les blocs se suivent, mais l’ensemble des données pour chaque enregistrement se trouve dans un espace contigu : 

1;The Matrix;1999;The Wachowskis 
 2;The Matrix Reloaded;2003;The Wachowskis 
 3;The Matrix Revolutions;2003;The Wachowskis 

L’un des problèmes associés à un stockage sous cette forme est que l’on est obligés de lire l’ensemble de la ligne depuis le disque même si on veut charger qu’une partie de la donnée. On est par exemple obligés de charger les titres depuis le disque même si la seule information que l’on veut récupérer est l’année de sortie de chaque film. 
Le fait de lire un ensemble relativement restreint de toutes les colonnes disponibles constitue un exemple prototypique du type de requêtes exécutées par nos clients dans un contexte analytique. 
Dans un format orienté colonne, chaque colonne est stockée de manière séparée : 

The Matrix:1;The Matrix Reloaded:2;The Matrix Revolutions:3 
1999:1;2003:2;2003:3 
The Wachowskis:1;The Wachowskis:2;The Wachowskis:3  

À première vue, cela peut ne pas sembler représenter une grande différence, mais en réalité, cette altération modifie tant les contraintes qu’il s’agit d’un vrai changement de paradigme. 
L’un des avantages immédiats est qu’il est maintenant beaucoup plus aisé de lire seulement les données de certaines colonnes. Cela implique moins d’entrées/sorties disque (disk I/O), et ceci est crucial car les entrées/sorties disque sont l’un des premiers facteurs limitant la performance. 
Un avantage un peu moins évident de ce changement de paradigme est que puisque les données d’une même colonne sont en général relativement homogènes, cela permet de la compresser de manière agressive en appliquant des algorithmes de compression adaptées, qui peuvent même être choisis à la volée et au cas-par-cas. 
Pour donner un aperçu, notre exemple précédent par exemple, les colonnes date et auteur pourraient être stockées : 

1999:1;2003:2,3 
The Wachowskis:*  

De nombreuses optimisations sont possibles, mais celles-ci ne sont mentionnées ici qu’à titre d’exemple afin de vous donner une idée des possibilités offertes par ce type de format. 
La plupart des SGBDs sur le marché offrent des options permettant de stocker les données au format colonne. Microsoft SQL Server, la base de données traditionnellement utilisée par AT Internet, par exemple, est capable de gérer le format colonne et cette fonctionnalité est utilisée depuis maintenant plusieurs années dans nos bases. En revanche, la donnée dans ces bases reste normalisée, contrairement à ce que l’on fait dans la New Data Factory. 

Quelques mots à propos d’Apache Parquet 

Le site officiel d’Apache Parquet définit le format comme : 
Un format de stockage colonne disponible pour tout produit dans l’écosystème Hadoop, peu importe le choix du framework de traitement, modèle de données ou langage de programmation. 

Cette technologie est l’une des plus populaires implémentations d’un format de fichier orienté colonne. 
L’un des aspects sur lesquels je voudrais insister est qu’il s’agit bien d’un format de fichier et pas d’un système de gestion de base de données. C’est une distinction importante, notamment car cela implique qu’étant constitué de simples fichiers, un datalake parquet peut être stocké où vous le souhaitez, que ce soit dans votre baie de stockage SAN, dans un datacenter, ou encore dans un serveur de calcul dans le cloud. 
Adopter un tel format de stockage permet ainsi de partir sur une base saine compatible avec le principe de découplage du calcul et du stockage, un des principes prévalents dans le stockage big data et que nous essayons de suivre en tant qu’ingénieurs de la donnée chez AT Internet. 

Nous n’aurons pas le temps de couvrir dans cet article l’ensemble des fonctionnalités de ce format Apache Parquet, mais voici un bref résumé de ses caractéristiques les plus utiles : 

  • Parquet est capable de gérer nativement des structures de données imbriquées. 
  • Les valeurs vides (NULL) sont gérées nativement et ne coûte presque rien en stockage. 
  • Les fichiers parquets sont auto-descriptifs. (Le schéma est contenu dans chaque fichier) 
  • Les moteurs gérant le format parquet sont capable de découvrir dynamiquement le schéma d’un data lake Parquet. (mais cette découverte peut prendre un certain temps). 
  • Ce format permet le “predicate push-down” nativement grâce à l’élimination de “row-groups”. Cela veut dire qu’il est possible de ne charger depuis le disque que la partie de la donnée qui nous intéresse vraiment lorsqu’on filtre un fichier parquet. 
  • Vastement supporté dans les divers outils de l’écosystème Big Data 

Un dernier aspect important à mentionner en ce qui concerne ce format est le partitionnement. Dans un data lake parquet, les fichiers sont en général rangés dans des répertoires correspondant à l’une des colonnes de la donnée. C’est ce qu’on appelle le partitionnement. Si on range nos fichiers par date, on peut donc avoir par exemple : 


|- date=2019-01-01/data.parquet 
|- date=2019-01-02/data.parquet 
|- ... 

Un partitionnement par date ou par heure constitue souvent un choix naturel et efficace pour de la donnée collectée sous la forme d’un flux ininterrompu. Le partitionnement permet de requêter la donnée de manière performante en allant cibler directement les fichiers susceptibles de contenir la donnée que l’on requête. 

Pas la panacée : des pièges… et des solutions 

Outre les aspects positifs de ce changement de paradigme, de nouvelles contraintes et difficultés apparaissent; difficultés auxquelles il faut trouver des solutions. Voyons ensemble quelques-unes de ces problématiques ainsi que des pistes permettant d’en limiter les désagréments. 

La mise à jour des données 

Parquet n’offre pas de manière native de mettre à jour seulement quelques lignes dans un fichier. Si cela doit être réalisé, une ré-écriture complète du fichier est nécessaire. 
Heureusement, dans la plupart des workflows Big Data, la donnée est “Write once, Read many times”, ce qui mitige le problème dans ce contexte. Un bon partitionnement de la donnée permet aussi d’améliorer la situation car cela permet de mettre à jour une ou certaines partitions indépendamment du reste du Data Lake. 
Dans le cas où l’on sait à l’avance que certaines données sont amenées à évoluer fréquemment, une solution possible consiste à les re-normaliser. 

Propriétés à géométrie variable 

En fonction de la manière dont les fichiers sont écrits et du type de technologie où elles sont stockées (cluster hadoop, S3, système de fichier local), le data lake ne possède pas exactement les mêmes propriétés, notamment en termes d’atomicité des opérations. 
En tant qu’ingénieur de la donnée, il est donc important de bien connaître et maîtriser les propriétés du système de fichiers hébergeant son data lake afin de ne pas réaliser de contre-sens. 

Gestion des transactions 

La gestion des transactions doit être réalisée à la main : si plusieurs processus écrivent et lisent les mêmes données, la synchronisation de ces processus doit être réalisée manuellement afin de ne pas lire la donnée dans un état corrompu. 
Les outils de traitement de la donnée comme Apache Spark possèdent nativement des connecteurs permettant d’écrire de manière transactionnelle pour la plupart des systèmes des fichiers. Dans les cas où il serait impossible d’utiliser ces fonctionnalités, il reste toujours possible d’implémenter un système de locks distribués pour réguler les accès en lecture et écriture au Data Lake. 

Tri des données au sein d’un fichier 

La distribution de la donnée à l’intérieur d’une partition et son tri à l’intérieur d’un même fichier parquet est importante et conditionne grandement la taille des fichiers écrits. 
Il n’y a pas de solution miracle pour ce point-ci. Il est très important de connaître la donnée traitée afin de bien choisir le tri à appliquer. Une des meilleures approches est de tester différentes clés de partitionnement, le but étant de regrouper les données similaires dans les mêmes groupes de lignes Parquet. 

Prenons du recul 

Plusieurs des problèmes évoqués ci-dessus sont une forme ou une autre de perte d’acidité, et la plupart des technologies sur lesquelles se basent les data lakes contemporains en souffrent. Ces problèmes étant très généraux, la communauté big data travaille sur des solutions, solutions qui commencent à émerger ; et dont quelques mentions honorables sont Delta LakeACID Orc ou encore Iceberg. Ces technologies sont prometteuses et devraient permettre à moyen terme de ne plus avoir à se préoccuper des considérations mentionnées plus haut. 

Concluons 

Nous avons vu dans cet article ce qu’était la normalisation, et les formats de stockage ligne et colonne. Nous avons aussi pu voir pourquoi dans les workflows big data, le format colonne est privilégié, pourquoi cela ouvre la porte à un enregistrement des données dans un format dénormalisé, et cela nous a amené à présenter le format de fichier Apache Parquet. 
L’écosystème étant en constante évolution, en tant qu’ingénieurs de la donnée dans une entreprise traitant autant de données qu’AT Internet, nous avons la responsabilité de rester à jour et continuer à adapter les chaînes de traitement en utilisant les outils les plus efficaces de manière à apporter la meilleure valeur à nos clients, et nous espérons pouvoir vous parler d’autres de ces outils dans de prochains articles. 
Si vous avez trouvé cet article intéressant, n’hésitez pas à consulter le site web d’AT Internet pour découvrir notre solution. 

Author

Ingénieur de la donnée. Yacine travaille sur les problématiques techniques liées au traitement et au stockage de la donnée chez AT Internet. Cela fait maintenant quatre ans que ces sujets l'occupent au quotidien. En plus de son intérêt pour les technologies de traitement de la donnée, Il s'intéresse à l'algorithmique, aux bonnes pratiques de développement et à la programmation fonctionnelle.

Comments are closed.