La recommandation de A à Z [2/3] : transformer la donnée avec AWS Glue - Mixpanel
Analytics produit

La recommandation de A à Z [2/3] : transformer la donnée avec AWS Glue

Johan Chataigner

Cet article a été initialement publié sur medium.com

Dans cet article, notre objectif va être de montrer comment grâce à AWS Personalize il est possible de créer un moteur de recommandations à partir des données de tracking de Mixpanel. Nous allons utiliser comme support une simple application mobile reproduisant les interactions basiques de youtube : aimer, rechercher et regarder des vidéos de chaînes YouTube. Notre idéal est de permettre à l’utilisateur de voir le contenu qui lui est proposé être constamment mis à jour par la recommandation en fonction de son utilisation de l’application.

Cet article est le second d’une série de trois, dans lequel nous allons précisément explorer comment transformer les événements exportés de Mixpanel grâce à AWS Glue.

Pour reprendre là où le précédent article nous a laissés, nous débutons avec plusieurs fichiers JSON, partitionnés par année, mois et jour. Chacun contient des entrées avec ou des entités (utilisateurs/contenus), ou des interactions entre les entités. Toute cette donnée est totalement brute, et ne peut être exploitée directement.

A la fin de cet article, nous aurons à notre disposition nos datasets (fichiers JSON) transformés. Grâce à des passes de nettoyage et d’enrichissement, nous constituerons un nouveau dataset prêt à être exploité pour AWS Personalize.

Si vous connaissez déjà AWS Glue, nous vous invitons à aller directement au prochain article : La recommandation de A à Z : créer et exposer un modèle Personalize. Si vous n’avez pas lu l’article précédent et que vous aimeriez en savoir plus à propos du Tracking Utilisateur, Mixpanel et leurs Pipelines Data, nous vous recommandons de regarder La recommandation de A à Z : le tracking utilisateur et l’export de la donnée vers AWS S3 avec Mixpanel.

AWS

A quoi sert Glue ETL et comment allons-nous l’utiliser ?

AWS Glue est le service d’ETL d’Amazon Web Services. Cet outil est divisé en trois “sous-outils” distincts : Glue CatalogGlue Jobs et Glue Crawlers. Dans la partie précédente, nous avons déjà vu à quoi pouvaient nous servir Glue Catalog et les Glue Crawlers. Parlons maintenant du rôle principal de Glue : l’Extract-Transform-Load.

« Il s’agit d’une technologie informatique permettant d’effectuer des synchronisations massives d’information d’une source de données vers une autre. Selon le contexte, on est amené à exploiter différentes fonctions, souvent combinées entre elles : « extraction », « transformation », « constitution » ou « conversion », « alimentation ». » (wikipédia)

l’ETL résumé en un schéma

Dans des termes moins abstraits, une tâche ETL est souvent un script Python récupérant de la donnée d’une ou plusieurs sources, appliquant des transformations dessus, puis redirigeant ses résultats dans un lieu de stockage précis. Par exemple, nous souhaitons prendre la donnée JSON de nos datasets S3 bruts, la transformer, et en créer de nouveaux datasets cette fois-ci en CSV vers une nouvelle destination S3. Le code Python utilise souvent des outils et bibliothèques connus pour leur utilité en Data Science : sparknumpypandas, …

Dans notre cas, nous disposons d’utilisateurs et d’événements entre utilisateurs et contenus (vidéo aimée, souscription à une chaîne, vidéo regardée, …). Un résultat idéal serait 5 donc nouveaux datasets : usersvideoschannelsusers-videos-interactionsusers-channels-interactions. Pour ce faire, nous allons parcourir toute notre donnée brute et utiliser des fusions (merge), jointures, suppressions, du feature engineering, … .

Elaborer votre processus Glue (Glue Job)

Création du processus et éditeur visuel

L’interface de Glue Jobs se divise en deux. La première partie (celle d’arrivée) permet de directement créer et d’éditer des processus grâce à un simple script Python. Cette manière de faire sera certainement très adaptée pour un utilisateur expérimenté, mais nous préférons quelque chose de plus simple et plus “rapide” à utiliser (et encore plus pour des tâches élémentaires).La seconde partie de l’interface, Glue Studio, est un éditeur WYSIWYG où vous pouvez sélectionner comment vous désirez transformer votre donnée. Assez classiquement, c’est un graphe orienté dont les noeuds sont les opérations (sources, destinations, transformations). Le résultat en sortie n’est rien d’autre que le même script Python, mais dont le contenu aura été généré. Cela dit, vous avez par la suite toujours la possibilité de modifier manuelle ce script.Pour démarrer avec Glue Studio, rendez-vous sur AWS Glue dans Amazon Web Services, et sélectionnez l’onglet “Glue Studio” dans le menu sur la gauche. Vous pouvez directement choisir “View Jobs” pour directement accéder à l’interface de création et d’édition.Commençons avec notre processus : nous allons démarrer avec un exemple déjà pré-rempli pour ne modifier que certains détails. Nous voulons extraire la donnée JSON d’un bucket S3, et l’exporter en donnée CSV vers un autre bucket S3.

Création d’un processus

Nous pouvons maintenant voir notre éditeur et les noeuds du graphe. Tout se résume maintenant à éditer les propriétés de ces noeuds.

Dans l’onglet “script”, il est possible de constater le code généré via ce graphe. Pour récupérer la donnée, le script utilise AWS Glue SDK et la bibliothèque Python Apache Spark (pyspark)

Code python correspondant à l’exemple de base d’un processus Glue

Même si Spark n’est pas votre tasse de thé, il est tout de même possible de remarquer les quatre principales parties de ce script :

  • L’instanciation du processus, où une configuration lui est attachée en fonction du contexte d’exécution
  • Les sources, où la donnée est extraite via d’autres services AWS (en l’occurence Glue Data Catalog ou S3). Ceci concerne la partie “extraction” de l’ETL.
  • Les transformations, où son appliquées des opérations d’agrégation, de feature engineering, … . C’est en toute logique la partie “T” de l’ETL.
  • Et finalement, les “datasinks”, littéralement la “chute de la donnée”. C’est-à-dire la destination vers laquelle nous allons exporter les résultats des transformations (en l’occurence, notre bucket S3). C’est donc la partie finale de “chargement” (load).

NB : Dans Glue Studio, il vous est impossible d’éditer manuellement le script Python. Pour ce faire, il vous faudra revenir à la première partie de l’interface d’AWS Glue et d’aller dans l’onglet “Jobs”.

Edition du processus

Revenons-en à notre éditeur WYSIWIG. Dans notre cas, nous utilisons le catalogue Glue Data Catalog que nous avons créé lors du précédent article de cette série. Celui-ci va nous permettre de configurer la source de données. Il suffit donc de cliquer sur le noeud source (nommé “Data source — S3 Bucket”), sélectionner la base Glue Data Catalog, la table concernée, et c’est tout ! Nous aurions pu également directement donner un chemin vers une ressource S3Glue Job est capable de lire plusieurs fichiers d’un même répertoire, et de baser son schéma de données sur leur contenu.

Configuration de la source de données

Nous pouvons continuer dans notre édition en passant à la partie transformations. Ici, nous nous limiterons à renommer quelques champs, et utiliser Spark SQL pour supprimer les doublons de notre dataset. Il ne vous reste donc qu’à créer les noeuds “Apply Mapping” et “Spark SQL”.

Pour terminer, nous exportons le résultat dans le bucket S3 de destination. Nous vous recommandons de sélectionner l’option permettant de créer automatiquement une table dans Glue Data Catalog. De cette manière, vous disposerez d’une définition du schéma de vos données que vous pourrez ensuite utiliser dans d’autres services (comme par exemple AWS Athena).

Glue Jobs peut être terriblement simple, comme s’avérer très compliqué. Pour l’illustrer, notre processus d’extraction d’utilisateurs n’a que deux opérations et ne nécessite qu’un seul dataset, alors que celui de l’extraction des vidéos a besoin de 4 datasets différents et de multiples opérations de fusion ou de jointure entre ces sources.

Un processus basique : l’extraction des utilisateurs

NB : Lorsque vous fusionnez des sources de données, vous aurez besoin d’une clé à partir laquelle faire les relations entre les enregistrements (comme pour du SQL). Le problème étant qu’avec Mixpanel, vous vous retrouvez souvent avec beaucoup de duplication dans les colonnes, car chaque donnée a un ensemble d’attributs qui sont communs à chaque événement. A moins que vous en ayez un usage particulier, il vous faudra les supprimer. Nous vous recommandons donc de toujours bien nettoyer vos données avant de faire les jointures pour s’éviter des indésirables dans le schéma final. Par exemple, pour créer notre entité “vidéo” nous avons besoin des événements comme “video-watched”, “video-liked”, “video-disliked”, “video-consulted”. A chaque fois, nous n’avons réellement besoin que d’un ou deux attributs, et rien des attributs calculés de Mixpanel (“mp_lib_version”, “mp_processing_time_ms”, …) qui ne sont que des métadonnées sans utilité directe.

Ici, le graphe plus lourd de l’extraction de vidéos prenant plusieurs sources et n’ayant qu’une seule destination. A chaque fois nous nettoyons la donnée grâce à des renommages et des suppressions. Nous agrégons finalement la donnée grâce à un noeud de code Spark SQL.

Graphe du processus d’extraction de vidéos

Détails d’un processus

Avant de valider notre processus, nous allons devoir configurer les détails finaux dans l’onglet “Job Details”. La plupart des champs peuvent être laissés à leurs valeurs par défaut, mais le rôle IAM et le Job Bookmark nécessitent d’être adaptés.

Page de détails d’édition du job

En ce qui concerne le rôle IAM, assurez-vous que ce dernier dispose des bonnes politiques attachées (accès à Glue, accès aux sources et destinations S3). Si vous souhaitez intégrer du logging à vos tâches, n’oubliez pas également d’attacher la politique d’accès à AWS CloudWatch, et de créer le groupe de logs associé dans CloudWatch.

Le Job Bookmark permet à votre processus de se souvenir de son dernier passage, et de ne recommencer qu’à partir de l’endroit où il s’était arrêté (et évite ainsi de re-traiter la totalité de vos datasets). C’est une fonctionnalité qui présente des intérêts, mais provoque malheureusement de temps à autres des erreurs à l’exécution. Dans notre cas vu que le dataset est très petit, nous nous permettons de la désactiver.

Votre processus d’ETL est maintenant prêt ! Une fois l’ensemble validé, il vous reste à appuyer sur le bouton “Run”. Suivant vos préférences, vous pouvez soit rester dans l’interface Glue Studio, soit revenir à la plus classique via l’onglet “Jobs” située sur la gauche de votre écran. L’interface n’est pas être pas des plus élaborées, mais elle a le mérite d’être plus riche en termes d’informations que l’autre. Par exemple, il vous sera possible de plus facilement voir les métriques du processus, les logs et raisons de ses erreurs, …

L’interface classique de Glue

Une fois que votre processus a terminé son exécution, vous pouvez constater le résultat soit dans S3, soit grâce à AWS AthenaAthena est un service interactif de requêtage type-SQL, capable de lire et d’écrire dans des Data Lakes. Son utilité se trouve notamment dans sa capacité à accéder et agréger des quantités potentiellement massives de données (sa tarification est d’ailleurs à la quantité de Gigaoctets lus). Pour l’utiliser, votre donnée doit être référencée dans un catalogue Glue Data Catalog. Si vous avez configuré votre processus Glue pour créer ce catalogue, AWS Athena s’offre à vous. Cela dit, Athena n’est pas réellement capable de comprendre convenablement des fichiers CSV et vous aurez probablement besoin de quelques combines pour obtenir des résultats convenables. C’est pour cela que nous vous recommandons d’utiliser Athena lorsque vous souhaitez davantage utiliser du JSON ou du Parquet.

La console de requêtage d’Athena

NB : Si jamais l’exécution de votre script s’est mal déroulée et que vous avez activé les logs CloudWatch, vous pouvez vous restreindre à ne regarder que les logs dont le nom s’apparente à “[…]-driver”, dans la partie “Logs” de vos logs de processus. Les parties “Output” et “Error logs” est rarement intéressante et contient principalement des données brutes de fonctionnement et des données d’Apache Spark.

Bonus : restreindre l’export à un seul fichier

Notre Glue Job exporte par défaut la donnée de manière partitionnée et en plusieurs fichiers. Pour faire en sorte de n’avoir qu’un seul et unique fichier en sortie, il vous faudra aller directement modifier le script du processus. Pour ce faire, dans l’interface classique des processus, sélectionnez celui concerné et cliquez sur “Script” (comme vous pouvez le constater sur l’avant-précédente image). Vous atterissez donc sur votre script généré et commenté. Nous avons besoin de dire à Spark de changer sa manière de partitionner la donnée pour être sûr qu’il ne tentera pas de l’exporter en plusieurs fichiers. Grâce à la méthode repartition, prenant en entrée un entier décrivant le nombre de partitions, il est possible de procéder à cette reconfiguration de la sortie.

A la fin de ce script, Glue a généré le noeud de destination via le nom “DataSink”. C’est ce noeud qui va récupérer la configuration de l’export et écrire dedans nos données. Il suffit donc de modifier la ligne appelant la fonction d’export pour qu’elle prenne la donnée repartitionnée plutôt que l’originale :

D’un export en plusieurs partitions à une unique

Et voilà ! Votre export est maintenant un unique fichier CSV.

NB : Assurez-vous de faire ces modifications qu’une fois le processus totalement édité dans la partie Glue Studio. Si jamais vous êtes amenés à remodifier cette partie, le script sera entièrement généré et vos modifications seront écrasées. Il vous faudra réecrire chaque bout de code manuellement ajouté.

Quid de la tarification ?

AWS Glue base ses prix sur ce que vous utilisez, sur une base horaire (mais facturée à la seconde). Concrètement, AWS calcule votre utilisation via son unité le DPU : Data Processing Units. Un DPU n’est rien de plus qu’une charge de travail utilisant 4vCPUs et 16 GB de RAM. Chaque processus Apache Spark a besoin d’au minimum 2 DPUs pour fonctionner, et Glue alloue par défaut 10 DPUs à ses processus. Chacun va tourner pour au minimum 1 minute. Sachant que le prix avoisinne les 0.44$ par DPU, par heure (variable suivant les régions AWS). Nous en déduisons la formule suivante …

Comme cela, vous pourrez estimer vos coûts d’utilisation de Glue

Dans notre cas, nos avons créé 5 Apache Spark Glue Jobs. Nous supposons que chacun va tourner pendant environ 5 minutes (300 secondes), et consommer 5 DPUs (nombre totalement arbitraire, il est probable que nous n’ayons pas besoin de ces 3 DPUs supplémentaires). En reprenant la formule précédente :

Ce qui revient à 0.91$, pour une exécution de l’ensemble de nos processus. Si l’on part du principe que l’on programme des exécutions à chaque export Mixpanel, c’est à dire potentiellement toutes les heures, le prix peut rapidement monter. Par exemple, pour un mois d’exécutions chaque heure : 0.91*24*30 = 660$.

Conclusion

Tout ce que nous venons de voir est dans l’idéal assez simple. Cela dit, notre exposé était simple car les entités et ce que nous souhaitons en faire est simple lui aussi. C’est pour ce que nous avons imaginé en amont ce dont nous avions réellement besoin et que devaient exactement faire les processus.

Nous vous encourageons à utiliser également AWS Athena, qui s’avère être particulièrement utile pour vérifier les entrées et sorties de vos processus Glue.

Si implémenter un moteur de recommandations avec AWS Personalize vous intéresse, nous vous recommandons de passer à la suite de cette série d’articles avec La recommandation de A à Z : création et exposition d’un modèle AWS Personalize.

Merci !

Get the latest from Mixpanel
This field is required.