Spark + EMR utilisant le paramètre "maximiserResourceAllocation" d'Amazon n'utilise pas tous les cœurs/vcores
J'exécute un cluster EMR (version emr-4.2.0) pour Spark en utilisant l'indicateur maximizeResourceAllocation
spécifique à Amazon, comme indiqué dans la documentation ici . Selon ces documents, "cette option calcule le maximum de ressources de calcul et de mémoire disponibles pour un exécuteur sur un nœud du groupe de nœuds principaux et définit les paramètres de défaut par défaut correspondants avec ces informations".
J'exécute le cluster à l'aide d'instances m3.2xlarge pour les nœuds de travail. J'utilise un seul m3.xlarge pour le maître YARN - la plus petite instance de m3 sur laquelle je peux le faire fonctionner, car il ne fait pas grand chose.
La situation est la suivante: lorsque j'exécute un travail Spark, le nombre de cœurs demandés pour chaque exécuteur est de 8. (Je ne l'ai reçu qu'après avoir configuré "yarn.scheduler.capacity.resource-calculator": "org.Apache.hadoop.yarn.util.resource.DominantResourceCalculator"
qui ne figure pas dans la documentation, mais je m'éloigne du sujet). Cela semble logique, car selon ces documents un m3.2xlarge a 8 "vCPU". Toutefois, sur les instances elles-mêmes, dans /etc/hadoop/conf/yarn-site.xml
, chaque noeud est configuré pour que yarn.nodemanager.resource.cpu-vcores
soit défini sur 16
. Je pense (à mon avis) que cela doit être dû à l'hyperthreading ou peut-être à une autre fantaisie matérielle.
Le problème est donc le suivant: lorsque j'utilise maximizeResourceAllocation
, j'obtiens le nombre de "vCPU" du type Instance Amazon, ce qui semble ne représenter que la moitié du nombre de "VCores" configurés que YARN exécute sur le noeud; par conséquent, l'exécuteur utilise seulement la moitié des ressources de calcul réelles sur l'instance.
Est-ce un bogue dans Amazon EMR? Est-ce que d'autres personnes rencontrent le même problème? Y a-t-il une autre configuration magique non documentée qui me manque?
D'accord, après beaucoup d'expérimentation, j'ai pu dépister le problème. Je vais présenter mes conclusions ici pour aider les gens à éviter la frustration à l'avenir.
- Bien qu'il y ait une différence entre les 8 cœurs demandés et les 16 VCores que YARN connaît, cela ne semble pas faire la différence. YARN n'utilise pas de groupes de contrôle ni quoi que ce soit de spécial pour limiter le nombre de processeurs que l'exécuteur peut réellement utiliser.
- "Cœurs" sur l'exécuteur est en fait un peu impropre. C'est en fait le nombre de tâches simultanées que l'exécuteur va exécuter volontairement à un moment donné; Cela se résume essentiellement au nombre de threads effectuant un "travail" sur chaque exécuteur.
- Lorsque
maximizeResourceAllocation
est défini, lorsque vous exécutez un programme Spark, il définit la propriétéspark.default.parallelism
comme étant le nombre de cœurs d'instance (ou "vCPU") pour toutes les instances non principales qui se trouvaient dans le cluster au moment de la création. Ceci est probablement trop petit, même dans les cas normaux; J'ai entendu dire qu'il est recommandé de définir à 4x le nombre de cœurs nécessaires pour exécuter vos tâches. Cela vous aidera à vous assurer qu'il y a suffisamment de tâches disponibles au cours d'une étape donnée pour occuper les processeurs sur tous les exécuteurs. - Lorsque vous avez des données provenant de différentes exécutions de programmes spark différents, vos données (au format RDD, Parquet ou autre) risquent fort d'être sauvegardées avec un nombre variable de partitions. Lorsque vous exécutez un programme Spark, veillez à repartitionner les données au moment du chargement ou avant une tâche gourmande en ressources processeur. Étant donné que vous avez accès au paramètre
spark.default.parallelism
au moment de l'exécution, il peut s'agir d'un numéro pratique pour la répartition.
TL; DR
maximizeResourceAllocation
fera presque tout pour vous correctement sauf ...- Vous souhaitez probablement définir explicitement
spark.default.parallelism
sur 4x nombre de cœurs d'instance sur lesquels le travail doit être exécuté, étape par étape (en langage EMR)/"application" (en langage YARN), c'est-à-dire définissez-le à chaque fois et... - Assurez-vous que dans votre programme que vos données soient correctement partitionnées (c’est-à-dire si vous voulez plusieurs partitions) pour permettre à Spark de les paralléliser correctement.
Avec ce paramètre, vous devriez obtenir un exécuteur sur chaque instance (sauf le maître), chacun avec 8 cœurs et environ 30 Go de RAM.
Est-ce que l'interface utilisateur de Spark à l'adresse http: //: 8088/ne montre pas cette allocation?
Je ne suis pas sûr que ce paramètre ait vraiment beaucoup de valeur par rapport à l’autre mentionné sur cette page, "Activer l’allocation dynamique des exécuteurs". Cela permettra à Spark de gérer son propre nombre d'instances pour un travail, et si vous lancez une tâche avec 2 cœurs de processeur et la 3G de RAM par exécuteur, vous obtiendrez un assez bon ratio CPU/mémoire pour l'instance d'EMR tailles.
dans la version 3.x d'EMR, cette requête a été implémentée avec une table de référence: https://github.com/awslabs/emr-bootstrap-actions/blob/master/spark/vcorereference.tsv
il est utilisé par un script Shell: maximize-spark-default-config
, dans le même dépôt, vous pouvez voir comment ils ont implémenté cela.
peut-être que dans la nouvelle version 4 d'EMR, cette table de référence était quelque peu fausse… Je pense que vous pouvez trouver tout ce script AWS dans votre instance EC2 d'EMR, qui devrait se trouver dans / usr/lib/spark/ opt/aws ou quelque chose comme ça.
dans tous les cas, vous pouvez au moins écrire vos propres scripts bootstrap action
dans EMR 4, avec une table de référence correcte, similaire à celle mise en œuvre dans EMR 3.x.
de plus, puisque nous allons utiliser l'infrastructure STUPS, il vaut la peine de jeter un coup d'œil à l'appliance STUPS pour Spark: https://github.com/zalando/spark-appliance
vous pouvez spécifier explicitement le nombre de cœurs en définissant le paramètre senza DefaultCores
lors du déploiement de votre cluster spark
voici quelques-uns des points forts de cet appareil par rapport au DME:
capable de l'utiliser même avec le type d'instance t2, auto-évolutif en fonction de rôles tels que celui d'autres appareils STUPS, etc.
et vous pouvez facilement déployer votre cluster en mode HA avec zookeeper, donc pas de SPOF sur le nœud maître, le mode HA dans EMR n’est toujours pas possible, et j’estime que EMR est principalement conçu pour les "grands clusters temporairement à travaux d’analyse ", pas pour" un cluster dédié allumé en permanence ", de sorte que le mode HA ne sera plus possible dans un avenir proche avec EMR.