Fermer

mars 21, 2021

Équilibrage des ressources entre les applications dans Spark


Spark, étant un moteur de traitement de données rapide et distribué, a repris le MapReduce traditionnel dans de nombreux cas d'utilisation. Avec le soutien continu de la communauté, les améliorations apportées à chaque version portent Spark vers de nouveaux sommets. Progress DataRPM exploite la puissance de calcul de Spark pour notre plate-forme de maintenance prédictive cognitive (CPdM) . Dans ce blog, j'aimerais partager mon expérience de travail avec Spark pour notre plate-forme CPdM, qui nous a vraiment simplifié la vie.

Chaque application Spark dispose d'un ensemble d'exécuteurs indépendants dédiés. Le même ensemble d'exécuteurs est utilisé pour tout calcul ou mise en cache de RDD ou DataFrames. Mais dans notre plate-forme CPdM, nous avons plusieurs applications fonctionnant en parallèle. Par exemple: la charge de données DataLake, les algorithmes d'apprentissage automatique, le nombre d'applications de découverte et de transformation de données, etc. En utilisant simultanément plusieurs applications, les ressources du cluster (mémoire et cœurs) peuvent s'épuiser car chaque application maintient les exécuteurs en cours d'exécution tant que l'application s'exécute. Et c’est un gros problème à résoudre.

Les ressources des exécuteurs sont toujours mesurées en termes de cœurs et de mémoire. Si nous sommes sûrs du type d'applications exécutées dans notre déploiement, il est toujours possible de contrôler les ressources de l'exécuteur en configurant –spark.executor.memory -spark.executor.cores . Mais cela ne fonctionne que pour un type de déploiement en laboratoire dans lequel seulement 1 ou 2 utilisateurs joueront autour de Spark avec de petites données. Mais dans le cas de BigData, il est toujours nécessaire de gérer de tels cas afin que nous ne nous retrouvions pas sous DOS (Denial Of Service) pour aucune application. La plupart des plates-formes de calcul distribuées fonctionnent sur YARN, où vous prendrez en charge de nombreux types d'applications ainsi que celles de Spark. Donc, en mettant toutes ces choses ensemble, il est tout à fait évident que la gestion des ressources est tout aussi importante que le codage d'une fonction de transformation efficace car cela pourrait conduire à une sous / surutilisation des ressources et les applications pourraient manquer de ressources pendant longtemps, ce qui amène la situation à ARRETEZ LE MONDE !!

Allocation dynamique des ressources

Spark dans la version 1.2 introduit l'allocation dynamique des ressources, dans laquelle il est possible de faire évoluer les exécuteurs de haut en bas en fonction des besoins. Jusqu'à la version 1.5.2 de Spark, cette fonctionnalité n'était disponible qu'avec YARN. Avec Spark 1.6, ceci est rendu disponible pour tous les types de déploiements: Standalone, Mesos, YARN.

Comment l'activer?

Voyons à quel point il est simple d'activer la même chose pour YARN.

  • Définissez le sous 2 propriétés sur true dans SparkConfig.

spark.dynamicAllocation.enabled
spark.shuffle.service.enabled

En plus de cela, pour activer le service de lecture aléatoire externe (expliqué plus loin) pour YARN, [19659008] localisez spark- <“version”> -yarn-shuffle.jar et ajoutez-le au chemin de classe de YARN Node Manager.

  • Dans yarn-site.xml, ajoutez spark_shuffle à yarn.nodemanager.aux-services. (avec mapreduce_shuffle si déjà présent)
  • Configurez yarn.nodemanager.aux-services.spark_shuffle.class en org.apache.spark.network.yarn.YarnShuffleService pour fournir l'implémentation pour le nouveau service shuffle de spark.
  • Redémarrez le service YARN.
  • Comment ça marche?

    Basé sur le nombre total –spark.executor.memory, –spark.executor.cores, –spark.tasks.cpus et de tâches le nombre d'exécuteurs requis sera calculé. Une fois que le nombre d'exécuteurs est calculé, celui-ci peut être demandé au maître d'application et à son tour communiquer avec le gestionnaire de ressources YARN pour demander le nombre souhaité de conteneurs à allouer afin que les exécuteurs soient exécutés. Ce processus se produit par lots lorsqu'il y a des tâches en attente pendant spark.dynamicAllocation.schedulerBacklogTimeout secondes, puis se déclenche à nouveau toutes les spark.dynamicAllocation.sustainedSchedulerBacklogTimeout secondes. Une fois l'exécution terminée, les conteneurs sont libérés et les exécuteurs inactifs pour spark.dynamicAllocation.executorIdleTimeout sont arrêtés explicitement par l'Application Master, de sorte que les autres applications en cours d'exécution peuvent demander plus d'exécuteurs.

    Important et intéressant à savoir …

    • La mise hors service des exécuteurs peut se produire lorsque l'application est toujours en cours d'exécution. Par conséquent, nous avons besoin de quelqu'un pour maintenir l'état. Un cas d'utilisation important pour cela sera pendant la phase de lecture aléatoire, une fois que l'exécuteur écrit la sortie de lecture aléatoire sur le disque, l'exécuteur peut être supprimé. Nous avons besoin de quelqu'un pour servir la sortie aléatoire à d'autres exécuteurs. Le Service de lecture aléatoire externe qui a été activé, résoudra en fait ce problème.

    Service de lecture aléatoire externe: Un processus de longue durée qui s'exécute sur chaque nœud indépendamment de l'application, sert la lecture aléatoire à d'autres exécuteurs, ce qui signifie que l'état de lecture aléatoire de tout exécuteur sera servi même après sa suppression.

     Picture1 "title =" Picture1 "/><ul data-recalc-dims=

  • La mise hors service des exécuteurs supprime toutes les données mises en cache que l'exécuteur détient. Mais cela ne se produira pas par défaut, car ces exécuteurs sont considérés pour la mise hors service uniquement sur la base de la configuration spark.dynamicAllocation.cachedExecutorIdleTimeout (qui est l'infini par défaut) où l'exécuteur est inactif pendant plus de ce délai.
  • Et maintenant?

    Connaître le riche ensemble de configurations avec la combinaison de spark.dynamicAllocation.initialExecutors spark.dynamicAllocation.maxExecutors spark.dynamicAllocation .minExecutors nous pouvons diviser les ressources du cluster entre les applications en définissant des propriétés Spark Config spécifiques pour chaque application afin que les ressources des applications ne se chevauchent pas et continuent à servir en parallèle.

     Picture2 "title =" Picture2 "/ ><h3 data-recalc-dims= Conclusion

    L'allocation dynamique des ressources supprime la plupart des maux de tête, un utilisateur doit subir pour résoudre des problèmes liés à la mémoire dans un environnement de calcul distribué, afin qu'il puisse se concentrer principalement sur le développement d'applications. La prise de conscience de l'importance d'un tel crochet fourni par Spark a vraiment simplifié la vie des ingénieurs.

    Happy Sparking 🙂




    Source link