• 6 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 19/05/2023

Analysez vos données par lot dans la Batch Layer

Vous souhaitez professionnaliser vos compétences ? Jetez un oeil sur les formations big datas proposées par OpenClassrooms : architecture big data

Premier des composants de notre Lambda architecture, la batch layer a deux des plus importantes responsabilités :

  • Stocker les données massives récoltées

  • Effectuer des calculs sur ces données massives

Revenons à l'exemple dont nous sommes partis : le décompte du nombre de visites des pages d'une application web. La batch layer va être en charge à la fois de stocker les informations représentant les visites et de réaliser différents calculs sur ces données : calculer le nombre total de visites par url ainsi que lister les 100 urls les plus visitées.

Les deux responsabilités de la batch layer vont être prises en charge par deux composants différents : l'un sera responsable du stockage, et l'autre du calcul.

All your data are belong to us

Le premier composant responsable du stockage est ce qu'on appelle le "master dataset". La création et l'administration d'un master dataset sont décrites en détail dans le cours Créez votre data lake, mais nous allons en rappeler certains éléments ici.

Comme nous l'avons vu dans le chapitre précédent, il est impératif de conserver les données brutes à partir desquelles on va faire des agrégations : même si notre programme qui réalise l'agrégation des données comporte une erreur, il doit toujours être possible de reconstituer le résultat agrégé correct à partir des données brutes. En ce sens, on dit que le master dataset est notre source de vérité. Les données qui y seront stockées sont considérées comme perpétuellement correctes : elles ne seront donc jamais supprimées ni modifiées. Par exemple : on doit stocker une liste d'utilisateurs caractérisés par leur adresse email, et cette adresse email est susceptible d'être modifiée. On ne va donc pas stocker l'adresse email de ces utilisateurs, mais tous les changements d'adresse. Ainsi, pour retrouver l'adresse email d'un utilisateur, il faudra lire la dernière adresse déclarée. S'il y a un jour une erreur dans le code de l'application qui modifie les adresses emails des utilisateur, il sera aisé d'ajouter des données au master dataset pour corriger cette erreur.

Notre master dataset sera contenu dans ce qu'on appelle un Data Lake et qui devra vérifier les contraintes énoncées dans la partie précédentes. Il se trouve que le support physique qui répond le mieux à ces contraintes est un système de fichiers distribués. Un tel système de fichier répond parfaitement à nos besoins :

  • Passage à l'échelle horizontal à bas coût

  • Lecture et écriture séquentielles rapides

C'est pourquoi, dans le cours dédié, on recommande d'employer le Hadoop Distributed Filesystem (HDFS) pour stocker le master dataset : sans rentrer ici dans les détails, il s'agit d'un système de fichiers distribués et qui stocke donc les données sur disque, de manière répliquée, sur différents serveurs.

Il est nécessaire de parler un peu de la manière dont nous allons stocker nos données : une des questions qui se pose est celle de la (dé)normalisation des données. Faut-il stocker les données de manière normalisée ou dénormalisée ? Pour rappel, des donnés dénormalisées dupliquent certains champs, tandis que des données normalisées évitent toute duplication en utilisant des ID. Par exemple, si nous devons stocker une liste de personnes ainsi que le modèle de leur voiture, on pourrait écrire les données de deux manières :

  • Dénormalisée :{username: "Régis", car: "Peugeot 405 Style"}dans la liste "users"

  • Normalisée :{username: "Régis", car_id: 843}dans la liste "users", et dans une autre liste "cars" :{id: 843, model: "Peugeot 405 Style"}

L'avantage de la forme dénormalisée est qu'elle permet de faire des requêtes sans avoir besoin de faire des jointures entre plusieurs sources de données. Mais son inconvénient est qu'elle nécessite de dupliquer des données. C'est à dire que si Luc conduit aussi une 405 Style, le nom du modèle va devoir être dupliqué. Et si ce nom doit un jour être modifié, pour une raison ou pour une autre, alors il va falloir le modifier pour Luc et Régis.

Cet inconvénient est suffisamment important pour qu'on décide de stocker les données dans notre master dataset dans un format normalisé.

Enfin, pour garantir la pérennité des données, il faut stocker le schéma des données avec elles. C'est quelque chose que fait très bien SQL, par exemple, mais nous n'utilisons pas SQL ici. Disposer du schéma des données nous garantit que les données de notre master dataset ne sont pas corrompues. Il faut donc sérialiser les données dans notre master dataset à l'aide d'un format qui embarque le schéma. Ce n'est pas le cas de tous les formats de sérialisation : par exemple, dans le format JSON on ne sait pas quel est le type des données. Il serait donc en théorie possible d'écrire dans notre master dataset :{username: "Régis", age: "YOLO"}. L'âge de l'utilisateur serait stocké sans garantir que c'est un entier, ce qui déclencherait des erreurs lors de l'exploitation des données.

Là aussi, l'utilisation d'un format de sérialisation (Apache Avro) est décrit en détail dans le cours correspondant, donc nous n'allons pas nous attarder dessus. Il est simplement important de comprendre que ce format de sérialisation doit être intelligible par le système responsable de l'exploitation des données.

Exploitation des données en batch

Le second composant de la batch layer est celui chargé de l'analyse des données massives contenues dans le master dataset. Reprenons notre exemple consistant à compter les visites des pages de notre site. Notre master dataset contient les pages visitées ainsi que l'heure de visite :

20171201-00:00:01 http://www.plonk.com/index.html
20171201-00:00:02 http://blog.plonk.com/article.html
20171201-00:00:05 http://www.plonk.com/about.html
20171201-00:00:10 http://www.plonk.com/index.html
...

(Ces données sont sérialisées dans un format binaire qui embarque leur schéma, mais nous les représentons ici sous forme de texte pour plus de simplicité.)

Gardons à l'esprit que ces visites peuvent représenter plusieurs giga ou teraoctets de données. Pour réaliser le décompte de ces visites, il faut donc une solution capable de traiter ces données en passant à l'échelle. Par ailleurs, ce passage à l'échelle doit pouvoir s'effectuer de manière horizontale, en ajoutant simplement des serveurs. On privilégie un passage à l'échelle horizontal pour des raisons de coûts : il est bien moins onéreux d'acheter (ou de louer) plusieurs serveurs ayant en tout 1000 processeurs plutôt qu'un seul serveur contenant 1000 processeurs.

On pourrait concevoir nous-mêmes une solution de calculs distribuées adaptée à notre problème spécifique. Mais c'est un problème qui a déjà été étudié et en grande partie résolue. Aujourd'hui, il existe des solutions de calculs distribuées capables de passer à l'échelle et adaptées à une grande variété de problèmes. Ces solutions sont basées sur Map/Reduce : il s'agit un cadre algorithmique général à partir duquel plusieurs implémentations ont été développées. En particulier, on retient Hadoop et Spark. Ces deux solutions sont décrites dans le cours Réalisez des calculs distribués sur des données massives. Retenons simplement ici qu'Hadoop et Spark permettent tous deux d'écrire des applications d'analyse de données qui peuvent être exécutées en parallèle sur des dizaines ou des milliers de serveurs. La tolérance aux pannes est gérée sans que le développeur ait à s'en préoccuper, ce qui correspond à notre besoin de maintenabilité énoncé dans le chapitre précédent.

Conclusion

Techniquement parlant, notre batch layer est donc composée de deux composants principaux : HDFS pour le stockage et Hadoop ou Spark pour l'analyse. Ces composants répondent à nos critères de bonne maintenabilité, de faible coût et de passage à l'échelle.

Maintenant, une fois qu'on a réalisé des analyses distribuées sur nos données, il faut stocker les résultats de ces analyses et les mettre à disposition des utilisateurs. C'est le rôle de la serving layer qu'on va voir dans le chapitre suivant.

Exemple de certificat de réussite
Exemple de certificat de réussite