Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici

Le framework Spark et ses rouages

Concepts et composants

1. Définition

Apache Spark est un projet open source (code source ouvert) appartenant à la fondation Apache. Il s’agit d’un framework permettant de réaliser de l’analyse de données ainsi que de l’apprentissage automatique. Sa particularité réside dans sa capacité à accomplir des traitements distribués. Ainsi, Spark peut effectuer des calculs sur de forts volumes de données.

Spark est écrit en Scala et présente des API dans plusieurs langages qui permettent d’interagir avec : Scala, Python, R et Java. D’autres initiatives ont vu le jour pour par exemple développer des applications Spark avec .NET. Nous ne les évoquerons pas. Nous nous concentrerons uniquement sur l’implémentation Python. Nous présenterons aussi quelques éléments que vous pouvez trouver spécialement dans Scala ou Java puisque ces deux API ont des différences notables.

Apache Spark est fortement soutenu par l’entreprise Databricks. Cette entreprise, fondée par les développeurs du framework, organise des cours, des certifications et des conférences autour du sujet. Le forum nommé Data + AI Summit contient notamment des présentations relatives à l’outil.

Ainsi, si vous souhaitez opérer des analyses de données sur de forts volumes, Apache Spark est un choix adéquat. Qu’il s’agisse d’apprentissage automatique ou de formes plus traditionnelles d’analyse, cette brique logicielle peut répondre aux besoins.

Les avantages de Spark sont non seulement sa capacité à travailler sur de fortes volumétries, mais aussi son API intuitive et ses possibilités d’interfaçage avec de nombreux autres systèmes, comme Kafka, HBase ou encore Cassandra. 

Apache Spark est un outil mature avec une forte communauté qui gravite autour. Samsung, Shopify, Yahoo et eBay, pour ne citer que quelques grands noms, le déploient en production. Cet outil n’est toutefois pas parfait et nous aurons le loisir d’évoquer ses limites.

Cependant, vous pouvez vous saisir de ce framework s’il correspond à vos besoins sans craindre des instabilités. Il n’est pas près de disparaître non plus....

Démarrer avec Spark

1. Installation sur une machine versus  installation sur un cluster

Spark est un framework pensé pour faire du calcul distribué. Ainsi, dans un environnement de production ou d’intégration, le framework peut être disponible sur un ensemble de machines capables de travailler ensemble. Nous parlons de cluster. Il est aussi possible d’avoir l’outil uniquement sur un ordinateur personnel.

Dans la section Un framework distribué, nous nous pencherons davantage sur le fait de faire communiquer des machines ensemble et les conséquences que cela entraîne du point de vue du développement. Pour l’heure, nous allons nous concentrer sur une installation/accès à Spark sur une seule machine. Si le terme « accès » est employé, c’est parce qu’il y a aujourd’hui des solutions en ligne où vous n’installez pas le framework, mais configurez un environnement pour y avoir accès.

Il y a plusieurs manières d’installer ou d’accéder à Spark. Après un rapide examen des solutions possibles nous expliquerons comment construire un environnement avec la plateforme Databricks. Cela vous permettra de suivre les différents exemples donnés tout au long du livre.

2. Solutions on-premise (sur site)

La première solution possible consiste à installer soi-même Spark sur une machine en local et sur un ensemble de machines en production.

PySpark est inclus automatiquement dans l’outil. Il est aussi possible d’y accéder via le gestionnaire de librairies pip, avec la ligne de commande suivante :

pip install pyspark 

Vous avez la possibilité d’installer PySpark avec conda, un gestionnaire de paquets assez apprécié dans la communauté Python. La ligne de commande est la suivante :

conda install pyspark 

En installant PySpark sur votre machine, vous ajoutez dans le même temps un outil fort utile qui s’appelle Spark Shell. En entrant la commande suivante dans votre terminal, vous ouvrez un environnement interactif dans lequel vous interagissez avec Spark :

pyspark 

C’est très pratique pour tester des fonctionnalités du framework ou faire de petites analyses de données.

Spark est souvent lié à...

Un framework distribué

1. Le concept de distribution

L’idée de système distribué apparaît dans plusieurs formes d’organisations. Commençons par une définition générale. Le principe est de faire collaborer différentes machines pour réaliser une même tâche. Historiquement, tout était toujours effectué sur un seul et même ordinateur. Pour avoir de la puissance de calcul, les informaticiens et informaticiennes ajoutaient de la mémoire vive ou des unités centrales de traitement. Le problème était que cela pouvait prendre du temps d’ajouter les éléments voulus. Il y avait aussi une interruption de service lors de l’installation. Au final, la machine était relativement coûteuse. Il devenait difficile d’étendre davantage les limites d’un seul et même ordinateur. De plus, si celui-ci rencontrait des incidents, les applications qui opéraient dessus se retrouvaient de facto elles aussi en panne.

Grace Hopper est la développeuse à l’origine du langage COBOL (Common Business-Oriented Language). Elle a aussi participé à l’expansion d’une idée aujourd’hui répandue : les systèmes distribués.

Grace Hopper serait aussi à l’origine du mot « bug » (« petite bête » en français) utilisé dans le domaine de l’informatique. Une personne de son équipe aurait trouvé un papillon de nuit coincé dans une machine et qui faisait planter le système.

L’idée avec les systèmes distribués est donc de réunir des machines dans un cluster pour les faire coopérer en vue de deux choses principalement : stocker des données et effectuer des actions. Au départ, il n’est pas possible d’exécuter les mêmes programmes en mode distribué ou non distribué. Comme nous le verrons tout au long de ce livre, Spark masque une partie de cette complexité. Dans la plupart des cas, les développeurs et développeuses ont du coup l’impression de ne communiquer qu’avec une seule machine.

images/01EP21.png

Cluster Spark

Quand une machine est ajoutée ou supprimée, c’est...

Les types d’exécution de Spark

1. Exécuter Spark

Il y a différents modes d’exécution dans Spark. Avant de les aborder, voyons comment exécuter du code Spark de manière générale. Avec la plateforme Databricks, vous n’êtes pas obligé de démarrer un objet SparkSession. Mais si vous exécutez Spark autrement, il y a des chances pour que vous y soyez contraint.

Importons l’objet et paramétrons-le :

from pyspark.sql import SparkSession 
 
spark: SparkSession = SparkSession \ 
    .builder \ 
    .appName("Une application Spark") \ 
    .getOrCreate() 

Après avoir importé l’objet SparkSession, nous lui appliquons builder. Puis nous donnons un nom à l’application Spark que nous sommes en train de créer. En ce sens, nous appelons la fonction appName. et nous lui passons le nom en argument. À la fin, nous appelons la méthode getOrCreate, ce qui signifie que SparkSession est construit comme un singleton. Il n’y a qu’un objet SparkSession. Ces lignes de code permettent de le créer quand il n’existe pas et de le modifier dans le cas contraire.

Il est possible d’ajouter des configurations grâce à la méthode config qui prend comme premier argument, la clé de configuration, et comme deuxième argument, la valeur. Si vous voulez changer la mémoire du pilote, vous pouvez utiliser la clé spark.driver.memory comme ceci :

from pyspark.sql import SparkSession 
 
spark: SparkSession = SparkSession \ 
    .builder \ 
    .appName("Une application Spark") \ 
    .config("spark.driver.memory"...

Le mode de fonctionnement interne

1. Les stages et les shuffles

Nous avons vu le concept de distribution d’une manière générale, la façon dont Spark a choisi de l’implanter ainsi que les différents modes d’exécution.

À présent, intéressons-nous à des concepts touchant au mode de fonctionnement interne du framework. Il y a quelques grandes lignes à connaître qui permettent d’éviter des bogues et des surprises.

L’outil découpe les traitements en stages (étapes). Un stage est le terme officiel pour désigner une unité dans laquelle Spark lance un lot de tâches. Les tâches sont elles-mêmes répliquées pour parvenir au calcul distribué dont notre outil est maître.

Les stages se suivent, déroulant les lots de tâches parallélisées.

images/01EP27.png

Les stages

Différentes transformations sont regroupées dans un même stage. Plus exactement, ce qui se retrouve dans ces lots, ce sont des transformations étroites, plus communément appelées narrow transformations. Cela signifie qu’il s’agit de traitements ayant la capacité d’être réalisés de manière indépendante sur leur partition sans avoir besoin d’autres données. Ils sont autonomes.

Dans Spark, il y a aussi des transformations larges. Le terme ici officiellement employé est wide transformations. Ces processus ont besoin d’accéder à d’autres données...

Lire et écrire des données

1. Principes de lecture, d’écriture et de transformation de données

Quand nous faisons du traitement de données - qu’il s’agisse d’analyse ou d’apprentissage automatique - par définition, il y a des données. On distingue les données qui constituent nos entrées, celles qui constituent nos sorties finales et enfin celles qui sont intermédiaires.

Les informations d’entrée sont généralement lues depuis différents chemins. Après des transformations, elles sont déposées là où c’est le plus judicieux pour le système en général. Elles pourront ainsi être utilisées par d’autres logiciels. Il est possible de créer des données intermédiaires.

images/01EP29.png

Processus de transformation classique

Les données d’entrée et de sortie peuvent être de différents formats. Par exemple, CSV (Comma Separated Value), JSON (JavaScript Object Notation), ou encore des formats plus spécifiques comme Parquet ou Avro. Nous pouvons aussi traiter avec différents systèmes, comme Kafka, Cassandra ou MySQL.

Ainsi, pour pouvoir lire et écrire des données, il nous faut des connecteurs d’entrée et de sortie. Certains sont internes au framework. C’est le cas du connecteur JSON. D’autres sont développés par la communauté. Pour les ajouter, il faut suivre les consignes fournies par chaque entité responsable du connecteur. Nous allons voir plus précisément dans cette section comment lire et écrire des données avec Spark. Nous examinerons les options offertes par l’outil ainsi que les principaux connecteurs.

Nous reviendrons sur la notion de transformation. Pour l’heure, disons qu’il s’agit d’effectuer des calculs sur les données afin de leur donner une valeur qu’elles n’avaient pas au départ. À titre d’exemple, imaginons que nous avons des prix en dollars et qu’à l’aide de données de conversion, nous ajoutons une colonne qui contient la valeur en euros.

2. Lire des données

Pour lire des données, nous pouvons à partir de l’objet SparkSession récupérer l’objet...

Types de données et schéma

1. Concepts de type et de schéma

En programmation, le concept de type a pour ambition de prémunir contre les erreurs. Il permet d’être sûr par exemple de manipuler une valeur au bon format. C’est aussi à partir de là que nous pouvons gérer les compatibilités. Si soudainement une variable est alimentée par un type auquel elle ne s’attend pas, une erreur est renvoyée. La manière dont cela est fait dépend des langages de programmation et des outils utilisés. Les types permettent aussi de caractériser une valeur et peuvent donc la rendre plus compréhensible.

Le concept de type s’applique aux données. Dans les bases de données, par exemple, nous pouvons définir des types. Un ensemble de types pour une ligne devient alors un schéma de base de données. En réalité, dans les bases, il y a différentes manières de gérer le schéma. Il y a des bases de données qui permettent de renseigner un schéma dès la création de l’entité que vous souhaitez écrire. Ainsi, il n’est pas possible d’écrire une nouvelle ligne dont le schéma ne correspond pas à celle attendue. C’est le cas de systèmes comme MySQL.

Il existe aussi des bases de données dites sans schéma. Ainsi, vous pouvez écrire des lignes ayant des structures différentes, ce qui peut être considéré comme un avantage dans certaines situations. Dans ce genre de configurations, vous avez tout de même à gérer un schéma, mais celui-ci se situe principalement en lecture. En écriture, vous écrivez ce que vous voulez. En lecture, c’est vous qui savez ce que vous attendez pour pouvoir faire vos traitements. Ainsi, il y a bien un schéma. Les bases de données de type MySQL en ont un à l’écriture. Ici, nous en avons un à la lecture. Il y a donc toujours une architecture, que nous la spécifions explicitement ou qu’elle soit implicite.

Nous avons vu à la section Lire et écrire des données que Spark est un framework qui interagit avec de nombreux formats et systèmes de données. Ainsi, selon les cas, vous devrez gérer...