Apache Spark : cas d’usage et fonctionnement

Apache Spark : cas d’usage et fonctionnement

Apache Spark s’est imposé ces dernières années comme la plateforme de prédilection pour traiter des données massives. À l’approche de sa 3e version majeure, cet article présente des cas d’usage pertinents pour l’adoption de cette technologie ainsi que son fonctionnement général.

Cas d’usage

Apache Spark est souvent considéré comme le successeur de la composante MapReduce de Hadoop. Cette technologie permet de transformer des données à grande échelle en exploitant les ressources de plusieurs machines simultanément. Cette parallélisation des calculs permet d’analyser facilement des gros volumes de données par batch, c’est-à-dire travailler sur toutes les données en même temps, mais également grâce à sa composante Spark Streaming, sur un flux continu de données.

Les cas d’usages sont nombreux et certaines entreprises utilisent Spark de manière intensive. Par exemple, pour le e-commerce, eBay propose des offres ciblées pour améliorer l’expérience du consommateur et Alibaba analyse des centaines de pétaoctets de données pour son système de recommandation. Netflix traite en temps réel les interactions des utilisateurs pour proposer une recommandation personnalisée. Pinterest utilise Spark pour détecter les nouvelles tendances pour les mettre en avant. TripAdvisor compare à l’aide de Spark des centaines de sites web pour proposer les meilleurs prix d’hôtels…

Si les cas d’usage emblématiques concernent de très gros volumes de données, Spark peut se révéler utile sur des données de taille plus raisonnable mais tout de même assez importante comme pour notre réalisation d’un système de recommandation pour le groupe M6. Il est également très courant d’utiliser Spark sur des volumes encore plus réduits qui sont très courants chez nos clients. Pour ce dernier cas, Spark est utilisé non plus pour traiter un gros volume de données mais pour paralléliser la recherche de paramètres pour un modèle de machine learning.

Revenons un instant sur ce qui a fait la popularité d’Apache Spark et facilité son adoption.

La fin de MapReduce

Big Data rime souvent avec Hadoop, plateforme majeure qui vise à utiliser un groupe de machines pour stocker, via sa composante HDFS, et traiter des données, via sa composante MapReduce. Spark a émergé par rapport à la composante MapReduce de Hadoop pour deux raisons fondamentales :

  • La première est sa rapidité d’exécution, principalement liée à l’utilisation de la mémoire vive pour stocker des résultats intermédiaires, là où MapReduce les stocke sur disque dur (ou SSD). Cette différence dans la façon de gérer la résilience (faculté à continuer de fonctionner en cas de panne d’une machine) se traduit par un gain en temps d’exécution : Spark est de 10 à 100 fois plus rapide que MapReduce.
  • La seconde est la qualité de son API. Celle-ci est en effet beaucoup plus haut niveau que celle de MapReduce et permet ainsi un développement sans peine de transformations complexes.

Nous consacrons la suite de cet article à présenter le deuxième point : l’API de Spark.

Data Engineer, Scientist ou Analyst : à chacun son API !

L’API de Spark a évolué au cours des années afin de proposer plusieurs façons de traduire des besoins métier en implémentation parallélisée et de satisfaire des types d’utilisateurs différents :

  • L’API initiale appelée RDD permet une gestion fine des ressources mais peut se révéler déroutante pour des utilisateurs non aguerris.
  • Une API plus haut niveau, appelée DataFrame, permet d’opérer sur des données tabulaires. Celle-ci propose des méthodes très similaires à la bibliothèque Python Pandas très appréciée des Data Scientists. Cette API est à privilégier puisque certaines optimisations non triviales sont faites automatiquement par Spark.
  • Apache Spark offre la possibilité d’écrire des requêtes SQL qui sont, à l’instar des DataFrames, automatiquement traduites en instructions Spark de plus bas niveau (en faisant appel à l’API RDD). Cette API est beaucoup plus simple à utiliser pour des profils de data analysts qui sont déjà familiarisés avec le langage SQL.

Sous le capot

Si les APIs haut niveau (DataFrames et SQL) sont à privilégier puisqu’elles offrent une facilité d’écriture et une lisibilité du code ainsi que des optimisations automatiques, il est souvent important de bien comprendre leur fonctionnement. Ceci permet de concevoir un code qui passe à l’échelle (quand le volume de données à traiter devient important), et aussi de faciliter la compréhension des erreurs qui peuvent se produire lors de l’industrialisation.

Apache Spark repose sur la notion de Resilient Distributed Dataset (RDD). Un RDD est une collection de données distribuée, c’est-à-dire qui est répartie sur plusieurs partitions, qui peuvent être stockées sur des machines différentes. Cette parallélisation des données permet la parallélisation des calculs : la transformation des données peut se faire sur chacun des nœuds (ou machines) du cluster. Par exemple, pour la préparation d’une omelette géante, on pourrait disposer de milliers d’œufs répartis de telle manière que chaque personne participant à la confection de cet exploit dispose de quelques œufs. Chaque personne peut alors indépendamment casser puis battre les œufs.

Un RDD gère aussi la résilience, c’est-à-dire permet au programme de continuer de fonctionner en cas de panne, lorsqu’une machine n’est plus accessible. Pour cela, Spark enregistre la liste des opérations à faire. Si un résultat intermédiaire n’est plus disponible (suite à une panne), il suffit de relancer les mêmes opérations pour obtenir à nouveau le résultat. Ce principe peut s’appliquer à la cuisine : si les ingrédients de base d’un gâteau sont toujours disponibles (on suppose que les données d’entrée sont stockées sur un système résilient tel qu’une base de données ou HDFS), il suffit de suivre la recette pour obtenir le gâteau. Si on fait tomber l’appareil, il suffit de reprendre les ingrédients et de suivre la recette à nouveau pour reconstituer l’appareil.

La façon de gérer la résilience en cas de panne et de distribuer les calculs peut avoir un impact significatif sur le développement :

  • Lorsqu’une machine dysfonctionne, appliquer les transformations à nouveau sur les données met du temps. Il est alors nécessaire de placer judicieusement des checkpoints pour stocker des résultats intermédiaires en cache, et de prioriser les différents résultats intermédiaires (certains sont plus lents à reconstruire).
  • Chaque machine doit pouvoir être en mesure de traiter le volume de données qui lui est fourni, c’est-à-dire doit avoir la mémoire vive nécessaire. Une compréhension rigoureuse de ce qui est parallélisé et ce qui ne l’est pas permet d’éviter des écueils.

Pour aller plus loin

Il n’est pas toujours évident de monter en compétence sur une technologie distribuée telle que Spark. En effet, si les API sont a priori simples et permettent de développer un POC qui fonctionne sur une petite quantité de données, les choses se corsent lorsque les données deviennent plus volumineuses : des latences apparaissent avec la répartition des données sur les différentes machines et une parallélisation non optimale implique des lenteurs. Kernix, fort de son expérience depuis de nombreuses années, forme des ingénieurs (Formation professionnelle EDF avec l’Université Paris-Saclay) et des étudiants en data science (Master 2 à l’Université de Paris) à Spark et au big data. Nous proposons également de vous accompagner via une formation pour adopter Spark.

Quoi de neuf pour Spark 3.0 ?

La version 3.0 d’Apache Spark apporte son lot de nouveautés comme une optimisation plus poussée de l’exécution de requêtes (dynamic partition pruning et adaptative query execution), ou encore une API de haut niveau pour des calculs sur les graphes avec le langage Cypher (créé par Neo4J). La possibilité d’utiliser le GPU pour certaines opérations, et la prise en charge plus poussée de Kubernetes sont également au rendez-vous. Cette version majeure marque aussi la fin du support de la version 2 de Python, et propose Java 11 et Scala 2.12.

Ces évolutions majeures concordent avec nos expertises :

  • Kernix est pionnier dans l’utilisation du graph mining avec l’utilisation de Neo4j dans de nombreux projets (voir par exemple nos réalisations pour Deolan, SEB et La Poste).
  • L’utilisation du GPU est un prérequis pour la plupart des réalisations faisant intervenir le traitement d’images comme la détection d’objets (voir par exemple nos réalisations pour Eppik ou Enedis ou bien notre série d’articles 1, 2 et 3).
  • Kubernetes, associé aux conteneurs Docker permet un déploiement aisé de nos applications.
Apache Spark : cas d’usage et fonctionnement