Tutoriel: architecture d'application et clusters Spark

Obtenez le livre complet
Analyse de données avec Spark utilisant Python (Addison-Wesley Data & Analytics Series) PDSF 44,99 $ Voir

Cet article est un extrait du livre Pearson Addison-Wesley «Data Analytics with Spark Using Python» de Jeffrey Aven. Reproduit ici avec la permission de Pearson © 2018. Pour plus d'informations, visitez informit.com/aven/infoworld.

Avant de commencer votre parcours en tant que programmeur Apache Spark, vous devez avoir une solide compréhension de l'architecture des applications Spark et de la manière dont les applications sont exécutées sur un cluster Spark. Cet article examine de près les composants d'une application Spark, examine comment ces composants fonctionnent ensemble et comment les applications Spark s'exécutent sur des clusters autonomes et YARN.

Anatomie d'une application Spark

Une application Spark contient plusieurs composants, qui existent tous, que vous exécutiez Spark sur une seule machine ou sur un cluster de centaines ou de milliers de nœuds.

Chaque composant a un rôle spécifique dans l'exécution d'un programme Spark. Certains de ces rôles, tels que les composants client, sont passifs pendant l'exécution; d'autres rôles sont actifs dans l'exécution du programme, y compris les composants exécutant des fonctions de calcul.

Les composants d'une application Spark sont:

  • le conducteur
  • le maître
  • le gestionnaire de cluster
  • les exécuteurs testamentaires

Ils fonctionnent tous sur des nœuds de travail, aka workers.

La figure 1 montre tous les composants Spark dans le contexte d'une application autonome Spark.

Pearson Addison-Wesley

Tous les composants Spark, y compris les processus du pilote, du maître et de l'exécuteur, s'exécutent sur des machines virtuelles Java. Une JVM est un moteur d'exécution multiplateforme qui peut exécuter des instructions compilées en bytecode Java. Scala, dans lequel Spark est écrit, se compile en bytecode et s'exécute sur des JVM.

Il est important de faire la distinction entre les composants d'application d'exécution de Spark et les emplacements et les types de nœuds sur lesquels ils s'exécutent. Ces composants s'exécutent à différents endroits en utilisant différents modes de déploiement, alors ne pensez pas à ces composants en termes de nœud physique ou d'instance. Par exemple, lors de l'exécution de Spark sur YARN, il y aurait plusieurs variantes de la figure 1. Cependant, tous les composants illustrés sont toujours impliqués dans l'application et ont les mêmes rôles.

Pilote Spark

La vie d'une application Spark commence et se termine avec le pilote Spark. Le pilote est le processus que les clients utilisent pour soumettre des applications dans Spark. Le chauffeur est également responsable de la planification et de la coordination de l'exécution du programme Spark et du retour du statut et / ou des résultats (données) au client. Le pilote peut résider physiquement sur un client ou sur un nœud du cluster, comme vous le verrez plus tard.

SparkSession

Le pilote Spark est responsable de la création de SparkSession. L'objet SparkSession représente une connexion à un cluster Spark. La SparkSession est instanciée au début d'une application Spark, y compris les shells interactifs, et est utilisée pour l'intégralité du programme.

Avant Spark 2.0, les points d'entrée pour les applications Spark incluaient SparkContext, utilisé pour les applications principales Spark; le SQLContext et HiveContext, utilisés avec les applications Spark SQL; et le StreamingContext, utilisé pour les applications Spark Streaming. L'objet SparkSession introduit dans Spark 2.0 combine tous ces objets en un seul point d'entrée qui peut être utilisé pour toutes les applications Spark.

Grâce à ses objets enfants SparkContext et SparkConf, l'objet SparkSession contient toutes les propriétés de configuration d'exécution définies par l'utilisateur, y compris les propriétés de configuration telles que le maître, le nom de l'application et le nombre d'exécuteurs. La figure 2 montre l'objet SparkSession et certaines de ses propriétés de configuration dans un pysparkshell.

Pearson Addison-Wesley

Nom SparkSession

Le nom d'objet de l'instance SparkSession est arbitraire. Par défaut, l'instanciation SparkSession dans les shells interactifs Spark est nommée spark. Par souci de cohérence, vous instanciez toujours SparkSession en tant que spark; cependant, le nom est à la discrétion du développeur.

Le code ci-dessous montre comment créer une SparkSession dans une application Spark non interactive, telle qu'un programme soumis à l'aide de spark-submit.

depuis pyspark.sql importer SparkSession

spark = SparkSession.builder \

  .master ("spark: // sparkmaster: 7077") \

  .appName ("Mon application Spark") \

  .config ("spark.submit.deployMode", "client") \

  .getOrCreate ()

numlines = spark.sparkContext.textFile ("fichier: /// opt / spark / licenses") \

  .compter()

print ("Le nombre total de lignes est" + str (numlines))

Planification des applications

L'une des principales fonctions du pilote est de planifier l'application. Le pilote prend l'entrée de traitement de l'application et planifie l'exécution du programme. Le pilote prend toutes les transformations demandées (opérations de manipulation de données) et actions (demandes de sortie ou invites à exécuter des programmes) et crée un graphe acyclique dirigé (DAG) de nœuds, chacun représentant une étape de transformation ou de calcul.

Graphe acyclique dirigé (DAG)

Un DAG est une construction mathématique couramment utilisée en informatique pour représenter les flux de données et leurs dépendances. Les DAG contiennent des sommets (ou nœuds) et des arêtes. Les sommets dans un contexte de flux de données sont des étapes du flux de processus. Les arêtes d'un DAG relient les sommets les uns aux autres dans une orientation dirigée et de telle sorte qu'il est impossible d'avoir des références circulaires.

Un DAG d'application Spark se compose de tâches et d' étapes . Une tâche est la plus petite unité de travail planifiable dans un programme Spark. Une étape est un ensemble de tâches qui peuvent être exécutées ensemble. Les étapes dépendent les unes des autres; en d'autres termes, il existe des dépendances d'étape .

Dans un sens de planification de processus, les DAG ne sont pas uniques à Spark. Par exemple, ils sont utilisés dans d'autres projets d'écosystème Big Data, tels que Tez, Drill et Presto pour la planification. Les DAG sont fondamentaux pour Spark, il vaut donc la peine de se familiariser avec le concept.

Orchestration des applications

Le conducteur coordonne également le déroulement des étapes et des tâches définies dans le DAG. Les principales activités motrices impliquées dans la planification et l'exécution des tâches sont les suivantes:

  • Garder une trace des ressources disponibles pour exécuter les tâches.
  • Planification des tâches pour qu'elles s'exécutent «près» des données lorsque cela est possible (le concept de localité des données).

Autres fonctions

Outre la planification et l'orchestration de l'exécution d'un programme Spark, le pilote est également chargé de renvoyer les résultats d'une application. Il peut s'agir de codes de retour ou de données dans le cas d'une action demandant le renvoi de données au client (par exemple, une requête interactive).

Le pilote sert également l'interface utilisateur de l'application sur le port 4040, comme illustré à la figure 3. Cette interface utilisateur est créée automatiquement; il est indépendant du code soumis ou de la manière dont il a été soumis (c'est-à-dire utilisation interactive pyspark ou utilisation non interactive spark-submit).

Pearson Addison-Wesley

Si les applications suivantes se lancent sur le même hôte, des ports successifs sont utilisés pour l'interface utilisateur de l'application (par exemple, 4041, 4042, etc.).

Spark travailleurs et exécuteurs testamentaires

Les exécuteurs Spark sont les processus sur lesquels les tâches Spark DAG s'exécutent. Les exécuteurs réservent des ressources de processeur et de mémoire sur des nœuds esclaves, ou des nœuds de calcul, dans un cluster Spark. Un exécuteur est dédié à une application Spark spécifique et se termine lorsque l'application se termine. Un programme Spark se compose normalement de nombreux exécuteurs, travaillant souvent en parallèle.

En règle générale, un nœud de travail (qui héberge le processus exécuteur) a un nombre limité ou fixe d'exécuteurs alloués à tout moment. Par conséquent, un cluster - étant un nombre connu de nœuds - a un nombre fini d'exécuteurs disponibles pour s'exécuter à tout moment. Si une application nécessite des exécuteurs dépassant la capacité physique du cluster, ils sont planifiés pour démarrer lorsque d'autres exécuteurs terminent et libèrent leurs ressources.

Comme mentionné précédemment, les JVM hébergent des exécuteurs Spark. La JVM d'un exécuteur se voit allouer un tas , qui est un espace mémoire dédié dans lequel stocker et gérer des objets.

La quantité de mémoire allouée au tas JVM pour un exécuteur est définie par la propriété spark.executor.memoryou comme --executor-memoryargument pour le pyspark, spark-shellou les spark-submitcommandes.

Les exécuteurs stockent les données de sortie des tâches en mémoire ou sur disque. Il est important de noter que les travailleurs et les exécuteurs ne sont conscients que des tâches qui leur sont attribuées, tandis que le pilote est responsable de la compréhension de l'ensemble complet des tâches et des dépendances respectives qui composent une application.

En utilisant l'interface utilisateur de l'application Spark sur le port 404 x de l'hôte du pilote, vous pouvez inspecter les exécuteurs de l'application, comme illustré à la figure 4.

Pearson Addison-Wesley

Pour les déploiements de cluster autonomes Spark, un nœud de travail expose une interface utilisateur sur le port 8081, comme illustré à la figure 5.

Pearson Addison-Wesley

Le maître Spark et le gestionnaire de cluster

Le pilote Spark planifie et coordonne l'ensemble des tâches requises pour exécuter une application Spark. Les tâches elles-mêmes s'exécutent dans des exécuteurs, qui sont hébergés sur des nœuds de travail.

Le maître et le gestionnaire de cluster sont les processus centraux qui surveillent, réservent et allouent les ressources de cluster distribuées (ou conteneurs, dans le cas de YARN ou Mesos) sur lesquels les exécuteurs s'exécutent. Le maître et le gestionnaire de cluster peuvent être des processus distincts, ou ils peuvent se combiner en un seul processus, comme c'est le cas lors de l'exécution de Spark en mode autonome.

Maître des étincelles

Le maître Spark est le processus qui demande des ressources dans le cluster et les met à disposition du pilote Spark. Dans tous les modes de déploiement, le maître négocie les ressources ou les conteneurs avec les nœuds de travail ou les nœuds esclaves, suit leur état et surveille leur progression.

Lors de l'exécution de Spark en mode autonome, le processus maître Spark sert une interface utilisateur Web sur le port 8080 sur l'hôte maître, comme illustré à la figure 6.

Pearson Addison-Wesley

Maître Spark contre pilote Spark

Il est important de distinguer les fonctions d'exécution du pilote et du maître. Le nom maître peut être déduit pour signifier que ce processus régit l'exécution de l'application, mais ce n'est pas le cas. Le maître demande simplement des ressources et met ces ressources à la disposition du pilote. Bien que le maître surveille l'état et la santé de ces ressources, il n'est pas impliqué dans l'exécution de l'application et la coordination de ses tâches et étapes. C'est le travail du conducteur.

Gestionnaire de cluster

Le gestionnaire de cluster est le processus chargé de surveiller les nœuds de travail et de réserver des ressources sur ces nœuds à la demande du maître. Le maître met ensuite ces ressources de cluster à la disposition du pilote sous la forme d'exécuteurs.

Comme indiqué précédemment, le gestionnaire de cluster peut être séparé du processus maître. C'est le cas lors de l'exécution de Spark sur Mesos ou YARN. Dans le cas de Spark s'exécutant en mode autonome, le processus maître exécute également les fonctions du gestionnaire de cluster. En effet, il agit comme son propre gestionnaire de cluster.

Le processus YARN ResourceManager pour les applications Spark s'exécutant sur des clusters Hadoop est un bon exemple de la fonction de gestionnaire de cluster. Le ResourceManager planifie, alloue et surveille la santé des conteneurs exécutés sur YARN NodeManagers. Les applications Spark utilisent ensuite ces conteneurs pour héberger les processus exécuteurs, ainsi que le processus maître si l'application s'exécute en mode cluster.

Applications Spark utilisant le planificateur autonome

Dans le chapitre 2, «Déploiement de Spark», j'ai expliqué le planificateur autonome comme une option de déploiement pour Spark. Là, j'ai déployé un cluster autonome Spark multinœud entièrement fonctionnel dans l'un des exercices du chapitre 2. Comme indiqué précédemment, dans un cluster Spark fonctionnant en mode autonome, le processus maître Spark exécute également la fonction de gestionnaire de cluster, régissant les ressources disponibles sur le cluster et les attribuer au processus maître pour une utilisation dans une application Spark.

Applications Spark exécutées sur YARN

Hadoop est une plate-forme de déploiement très populaire et courante pour Spark. Certains experts du secteur pensent que Spark remplacera bientôt MapReduce en tant que plate-forme de traitement principale pour les applications dans Hadoop. Les applications Spark sur YARN partagent la même architecture d'exécution mais présentent quelques légères différences d'implémentation.

ResourceManager en tant que gestionnaire de cluster

Contrairement au planificateur autonome, le gestionnaire de cluster dans un cluster YARN est YARN ResourceManager. ResourceManager surveille l'utilisation et la disponibilité des ressources sur tous les nœuds d'un cluster. Les clients soumettent des applications Spark au YARN ResourceManager. Le ResourceManager alloue le premier conteneur pour l'application, un conteneur spécial appelé ApplicationMaster.

ApplicationMaster en tant que maître Spark

L'ApplicationMaster est le processus maître Spark. Comme le processus maître le fait dans d'autres déploiements de cluster, ApplicationMaster négocie les ressources entre le pilote d'application et le gestionnaire de cluster (ou ResourceManager dans ce cas); il met ensuite ces ressources (conteneurs) à la disposition du pilote pour les utiliser comme exécuteurs pour exécuter des tâches et stocker des données pour l'application.

L'ApplicationMaster reste pour la durée de vie de l'application.

Modes de déploiement pour les applications Spark exécutées sur YARN

Deux modes de déploiement peuvent être utilisés lors de la soumission d'applications Spark à un cluster YARN: le mode client et le mode cluster. Regardons-les maintenant.

Mode client

En mode client, le processus du pilote s'exécute sur le client soumettant l'application. Il est essentiellement non géré; si l'hôte du pilote échoue, l'application échoue. Mode client est pris en charge pour les deux sessions shell interactif ( pyspark, spark-shellet ainsi de suite) et présentation de la demande noninteractive ( spark-submit). Le code ci-dessous montre comment démarrer une pysparksession à l'aide du mode de déploiement client.

$ SPARK_HOME / bin / pyspark \

--master fil-client \

--num-executors 1 \

--mémoire du pilote 512m \

- mémoire-exécuteur 512m \

--executor-cores 1

# OU

$ SPARK_HOME / bin / pyspark \

- fil maître \

- client en mode déploiement \

--num-executors 1 \

--mémoire du pilote 512m \

- mémoire-exécuteur 512m \

--executor-cores 1

La figure 7 présente une vue d'ensemble d'une application Spark exécutée sur YARN en mode client.

Pearson Addison-Wesley

Les étapes illustrées à la figure 7 sont:

  1. Le client soumet une application Spark au gestionnaire de cluster (YARN ResourceManager). Le processus de pilote, SparkSession et SparkContext sont créés et exécutés sur le client.
  2. Le ResourceManager affecte un ApplicationMaster (le maître Spark) à l'application.
  3. L'ApplicationMaster demande des conteneurs à utiliser pour les exécuteurs à partir du ResourceManager. Avec les conteneurs assignés, les exécuteurs se reproduisent.
  4. Le pilote, situé sur le client, communique ensuite avec les exécuteurs pour organiser le traitement des tâches et des étapes du programme Spark. Le pilote renvoie la progression, les résultats et l'état au client.

Le mode de déploiement client est le mode le plus simple à utiliser. Cependant, il n'a pas la résilience requise pour la plupart des applications de production.

Mode cluster

Contrairement au mode de déploiement client, avec une application Spark exécutée en mode cluster YARN, le pilote lui-même s'exécute sur le cluster en tant que sous-processus d'ApplicationMaster. Cela assure la résilience: si le processus ApplicationMaster hébergeant le pilote échoue, il peut être ré-instancié sur un autre nœud du cluster.

Le code ci-dessous montre comment soumettre une application à l'aide spark-submitdu mode de déploiement de cluster YARN. Étant donné que le pilote est un processus asynchrone exécuté dans le cluster, le mode cluster n'est pas pris en charge pour les applications shell interactives ( pysparket spark-shell).

$ SPARK_HOME / bin / spark-submit \

- cluster de fils maître \

--num-executors 1 \

--mémoire du pilote 512m \

- mémoire-exécuteur 512m \

--executor-cores 1

$ SPARK_HOME / examples / src / main / python / pi.py 10000

# OU

- fil maître \

- cluster en mode déploiement \

--num-executors 1 \

--mémoire du pilote 512m \

- mémoire-exécuteur 512m \

--executor-cores 1

$ SPARK_HOME / examples / src / main / python / pi.py 10000

La figure 8 présente une vue d'ensemble d'une application Spark exécutée sur YARN en mode cluster.

Pearson Addison-Wesley

Les étapes illustrées à la figure 8 sont:

  1. Le client, un processus utilisateur qui appelle spark-submit, soumet une application Spark au gestionnaire de cluster (YARN ResourceManager).
  2. Le ResourceManager affecte un ApplicationMaster (le maître Spark) à l'application. Le processus de pilote est créé sur le même nœud de cluster.
  3. ApplicationMaster demande des conteneurs pour les exécuteurs à ResourceManager. les exécuteurs sont générés dans les conteneurs alloués à ApplicationMaster par ResourceManager. Le pilote communique ensuite avec les exécuteurs pour organiser le traitement des tâches et des étapes du programme Spark.
  4. Le pilote, exécuté sur un nœud du cluster, renvoie la progression, les résultats et l'état au client.

L'interface utilisateur Web de l'application Spark, comme indiqué précédemment, est disponible à partir de l'hôte ApplicationMaster dans le cluster; un lien vers cette interface utilisateur est disponible à partir de l'interface utilisateur de YARN ResourceManager.

Le mode local revisité

En mode local, le pilote, le maître et l'exécuteur s'exécutent tous dans une seule JVM. Comme indiqué précédemment dans ce chapitre, cela est utile pour le développement, les tests unitaires et le débogage, mais il a une utilisation limitée pour exécuter des applications de production car il n'est pas distribué et ne s'adapte pas. En outre, les tâches ayant échoué dans une application Spark exécutée en mode local ne sont pas réexécutées par défaut. Vous pouvez toutefois ignorer ce comportement.

Lors de l'exécution de Spark en mode local, l'interface utilisateur de l'application est disponible à l'adresse // localhost: 4040. Les interfaces utilisateur maître et travailleur ne sont pas disponibles lors de l'exécution en mode local.