Configuration de Spark sur YARN

Habr, bonjour ! Hier, lors de la rĂ©union dĂ©diĂ©e Ă  Apache Spark, des questions ont Ă©tĂ© posĂ©es par de nombreux participants concernant la configuration de cet outil. Nous avons dĂ©cidĂ© de partager notre expĂ©rience suite Ă  cela. Le sujet n'est pas simple — nous vous invitons donc Ă  Ă©galement partager votre expĂ©rience dans les commentaires, peut-ĂȘtre que nous avons compris ou utilisĂ© quelque chose de maniĂšre incorrecte.

Une petite introduction — comment nous utilisons Spark. Nous avons un programme de trois mois « SpĂ©cialiste des grandes donnĂ©es », et durant tout le deuxiĂšme module, nos participants travaillent avec cet outil. Par consĂ©quent, notre tĂąche en tant qu'organisateurs est de prĂ©parer un cluster pour une utilisation dans ce cadre.

Une particularitĂ© de notre utilisation est que le nombre de personnes travaillant simultanĂ©ment sur Spark peut ĂȘtre Ă©gal Ă  l'ensemble du groupe. Par exemple, lors d'un sĂ©minaire, lorsque tout le monde essaie et rĂ©pĂšte ce que notre enseignant propose. Cela peut parfois aller jusqu'Ă  40 personnes. Il n'y a probablement pas beaucoup d'entreprises dans le monde qui rencontrent un tel scĂ©nario d'utilisation.

Je vais ensuite expliquer comment et pourquoi nous avons choisi certains paramĂštres de configuration.

Commençons par le début. Spark peut fonctionner sur le cluster de 3 maniÚres : en mode standalone, en utilisant Mesos ou en utilisant YARN. Nous avons choisi la troisiÚme option car elle nous semblait logique. Nous avons déjà un cluster hadoop. Nos participants connaissent bien son architecture. Utilisons YARN.

spark.master=yarn

Ensuite, ça devient plus intĂ©ressant. Chacune de ces 3 options de dĂ©ploiement a 2 modes de dĂ©ploiement : client et cluster. D'aprĂšs documentation et divers liens sur Internet, on peut conclure que le mode client convient pour un travail interactif — par exemple, via un notebook jupyter, tandis que le mode cluster est plus adaptĂ© aux solutions de production. Dans notre cas, nous Ă©tions intĂ©ressĂ©s par un travail interactif, donc :

spark.deploy-mode=client

En gros, Ă  partir de ce moment lĂ , Spark fonctionnera dĂ©jĂ  d'une certaine maniĂšre sur YARN, mais cela ne nous suffisait pas. Comme notre programme porte sur les Big Data, il arrivait parfois que les participants manquent de ce qui se prĂ©sentait dans le cadre d'une rĂ©partition uniforme des ressources. Et lĂ , nous avons dĂ©couvert une chose intĂ©ressante : l'allocation dynamique des ressources. Pour faire court, l'idĂ©e est la suivante : si vous avez une tĂąche lourde et que le cluster est libre (par exemple, le matin), grĂące Ă  cette option, Spark peut vous fournir des ressources supplĂ©mentaires. Le besoin est calculĂ© selon une formule astucieuse. Nous ne rentrerons pas dans les dĂ©tails — cela fonctionne assez bien.

spark.dynamicAllocation.enabled=true

Nous avons défini ce paramÚtre, et lors du lancement de Spark, une erreur s'est produite et il ne s'est pas lancé. C'est normal, car il fallait lire documentation plus attentivement. Il est indiqué que pour que tout soit en ordre, il faut également activer un paramÚtre supplémentaire.

spark.shuffle.service.enabled=true

Quel est son besoin ? Lorsque notre job ne nĂ©cessite plus autant de ressources, Spark doit les renvoyer au pool gĂ©nĂ©ral. La phase la plus coĂ»teuse en main-d'Ɠuvre dans presque n'importe quelle tĂąche MapReduce est la phase de Shuffle. Ce paramĂštre permet de conserver les donnĂ©es gĂ©nĂ©rĂ©es durant cette phase et ainsi de libĂ©rer les executors. Un executor est un processus qui calcule tout sur le worker. Il dispose d'un certain nombre de cƓurs processeurs et d'une certaine quantitĂ© de mĂ©moire.

Nous avons ajoutĂ© ce paramĂštre. Tout semblait fonctionner. Il est devenu Ă©vident que les participants recevaient rĂ©ellement plus de ressources quand ils en avaient besoin. Mais un autre problĂšme est survenu : Ă  un moment donnĂ©, d'autres participants se rĂ©veillaient et voulaient aussi utiliser Spark, mais tout Ă©tait occupĂ©, et ils Ă©taient mĂ©contents. On peut les comprendre. Nous avons commencĂ© Ă  consulter la documentation. Il s'est avĂ©rĂ© qu'il existe encore un certain nombre de paramĂštres qui peuvent influencer le processus. Par exemple, si un executor est en mode attente — au bout de combien de temps peut-on rĂ©cupĂ©rer les ressources ?

spark.dynamicAllocation.executorIdleTimeout=120s

Dans notre cas, si vos executors ne font rien pendant deux minutes, veuillez les renvoyer dans le pool gĂ©nĂ©ral. Cependant, ce paramĂštre n'Ă©tait pas toujours suffisant. Il Ă©tait Ă©vident qu'une personne ne faisait rien depuis longtemps, mais les ressources n'Ă©taient pas libĂ©rĂ©es. Il s'est avĂ©rĂ© qu'il existe un paramĂštre spĂ©cial pour dĂ©terminer au bout de combien de temps rĂ©cupĂ©rer les executors contenant des donnĂ©es en cache. Par dĂ©faut, ce paramĂštre Ă©tait dĂ©fini sur — infini ! Nous l'avons corrigĂ©.

spark.dynamicAllocation.cachedExecutorIdleTimeout=600s

Ainsi, si vos executors ne font rien pendant 5 minutes, renvoyez-les dans le pool gĂ©nĂ©ral. Dans ce mode, la vitesse de libĂ©ration et de distribution des ressources pour un grand nombre d'utilisateurs est devenue satisfaisante. Le nombre de mĂ©contents a diminuĂ©. Mais nous avons dĂ©cidĂ© d'aller plus loin et de limiter le nombre maximum d'executors pour une application — en gros, pour un participant au programme.

spark.dynamicAllocation.maxExecutors=19

Bien sĂ»r, il y a maintenant des mĂ©contents de l'autre cĂŽtĂ© — "le cluster est inactif, et je n'ai que 19 executors", mais que peut-on faire ? Il faut un certain Ă©quilibre correct. On ne peut pas rendre tout le monde heureux.

Et une autre petite histoire liĂ©e Ă  la spĂ©cificitĂ© de notre cas. Un jour, plusieurs personnes sont arrivĂ©es en retard Ă  la sĂ©ance pratique, et leur Spark ne s'est pas lancĂ© pour une raison quelconque. Nous avons vĂ©rifiĂ© le nombre de ressources disponibles — apparemment, il y en avait. Spark devait se lancer. Heureusement, d'ici lĂ , la documentation Ă©tait dĂ©jĂ  ancrĂ©e dans notre mĂ©moire, et nous nous sommes souvenus que lors du lancement, Spark recherche un port sur lequel se lancer. Si le premier port de la plage est occupĂ©, il passe au suivant. S'il est libre, il l'attrape. Et il existe un paramĂštre qui indique le nombre maximum de tentatives Ă  cet effet. Par dĂ©faut, il est de 16. Ce nombre est infĂ©rieur au nombre de personnes dans notre groupe de sĂ©ance. Donc, aprĂšs 16 tentatives, Spark abandonnait et disait qu'il ne pouvait pas dĂ©marrer. Nous avons corrigĂ© ce paramĂštre.

spark.port.maxRetries=50

Je vais maintenant parler de certains réglages qui ne sont pas vraiment liés à la spécificité de notre cas.

Pour un démarrage plus rapide de Spark, il est recommandé de compresser le dossier jars situé dans le répertoire domestique de SPARK_HOME et de le placer sur HDFS. Ainsi, il ne perdra pas de temps à charger ces jar files sur les workers.

spark.yarn.archive=hdfs:///tmp/spark-archive.zip

Il est également recommandé d'utiliser kryo comme sérialiseur pour un fonctionnement plus rapide. Il est plus optimisé que celui par défaut.

spark.serializer=org.apache.spark.serializer.KryoSerializer

Il y a un vieux problÚme avec Spark, c'est qu'il tombe souvent à court de mémoire. Cela se produit souvent lorsque les workers ont tout calculé et envoient le résultat au driver. Nous avons augmenté ce paramÚtre. Par défaut, il est de 1 Go, nous l'avons porté à 3.

spark.driver.maxResultSize=3072

Et enfin, comme dessert. Comment mettre à jour Spark vers la version 2.1 sur la distribution HortonWorks - HDP 2.5.3.0. Cette version de HDP contient une version préinstallée 2.0, mais un jour, nous avons décidé que Spark évoluait activement et que chaque nouvelle version corrigeait certains bugs tout en offrant des fonctionnalités supplémentaires, y compris pour l'API Python, donc nous avons décidé de faire la mise à jour.

Nous avons téléchargé la version sur le site officiel pour Hadoop 2.7. Nous l'avons décompressée, placée dans le dossier HDP. Nous avons créé les liens symboliques nécessaires. Nous lançons - ça ne démarre pas. Un message d'erreur trÚs incompréhensible s'affiche.

java.lang.NoClassDefFoundError: com/sun/jersey/api/client/config/ClientConfig

En cherchant sur Google, nous avons découvert que Spark a décidé de ne pas attendre que Hadoop se développe, et a choisi d'utiliser une nouvelle version de jersey. Ils se disputent à ce sujet sur JIRA. La solution était de télécharger jersey version 1.17.1. Nous l'avons placé dans le dossier jars de SPARK_HOME, à nouveau zipé et transféré sur HDFS.

Nous avons contourné cette erreur, mais une nouvelle erreur plutÎt obscure est apparue.

org.apache.spark.SparkException: L'application Yarn est dĂ©jĂ  terminĂ©e ! Elle a peut-ĂȘtre Ă©tĂ© tuĂ©e ou n'a pas pu lancer le maĂźtre d'application.

En essayant de lancer la version 2.0 — tout va bien. Essaie de deviner quel est le problĂšme. Nous avons plongĂ© dans les logs de cette application et avons vu quelque chose comme ça :

/usr/hdp/${hdp.version}/hadoop/lib/hadoop-lzo-0.6.0.${hdp.version}.jar

En gros, pour une raison quelconque, hdp.version n'a pas été résolue. AprÚs avoir cherché sur Google, nous avons trouvé une solution. Il faut aller dans Ambari, dans les paramÚtres YARN, et ajouter ce paramÚtre dans yarn-site personnalisé :

hdp.version=2.5.3.0-37

Cette magie a fonctionnĂ©, et Spark a redĂ©marrĂ©. Nous avons testĂ© quelques-uns de nos jupyter-notebooks. Tout fonctionne. Nous sommes prĂȘts pour notre premier cours sur Spark ce samedi (dĂ©jĂ  demain) !

MAJ. Au cours, nous avons dĂ©couvert un autre problĂšme. À un moment donnĂ©, YARN a cessĂ© de fournir des conteneurs pour Spark. Il fallait corriger un paramĂštre dans YARN, qui par dĂ©faut Ă©tait Ă  0.2 :

yarn.scheduler.capacity.maximum-am-resource-percent=0.8

C'est-à-dire que seulement 20 % des ressources ont participé à la distribution des ressources. En modifiant les paramÚtres, nous avons redémarré YARN. Le problÚme a été résolu et les autres participants ont également pu lancer le contexte Spark.

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster