Dans Hadoop v1, j'ai attribué à chaque mappeur et réducteur 7 emplacements d'une taille de 1 Go, mes mappeurs et réducteurs fonctionnent correctement. Ma machine a 8G de mémoire, 8 processeurs. Maintenant, avec YARN, lorsque je lance la même application sur la même machine, j'ai une erreur de conteneur. Par défaut, j'ai ces paramètres:
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>1024</value>
</property>
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>8192</value>
</property>
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>8192</value>
</property>
Cela m'a donné une erreur:
Container [pid=28920,containerID=container_1389136889967_0001_01_000121] is running beyond virtual memory limits. Current usage: 1.2 GB of 1 GB physical memory used; 2.2 GB of 2.1 GB virtual memory used. Killing container.
J'ai ensuite essayé de définir la limite de mémoire dans mapred-site.xml:
<property>
<name>mapreduce.map.memory.mb</name>
<value>4096</value>
</property>
<property>
<name>mapreduce.reduce.memory.mb</name>
<value>4096</value>
</property>
Mais toujours obtenir une erreur:
Container [pid=26783,containerID=container_1389136889967_0009_01_000002] is running beyond physical memory limits. Current usage: 4.2 GB of 4 GB physical memory used; 5.2 GB of 8.4 GB virtual memory used. Killing container.
Je ne comprends pas pourquoi la tâche de la carte nécessite autant de mémoire. Selon ma compréhension, 1 Go de mémoire est suffisant pour ma tâche de mappage/réduction. Pourquoi, alors que j'attribue plus de mémoire au conteneur, la tâche en utilise plus? Est-ce parce que chaque tâche est plus fractionnée? Je pense qu'il est plus efficace de réduire un peu la taille du conteneur et de créer plus de conteneurs afin que davantage de tâches s'exécutent en parallèle. Le problème est comment puis-je m'assurer que chaque conteneur ne se verra pas attribuer plus de divisions qu'il ne peut en gérer?
Vous devez également configurer correctement les allocations de mémoire maximales pour MapReduce. De ce tutoriel HortonWorks :
[...]
Chaque machine de notre cluster dispose de 48 Go de RAM. Une partie de cette RAM devrait être> réservée à l'utilisation du système d'exploitation. Sur chaque nœud, nous assignerons 40 Go RAM pour> YARN et en conserverons 8 pour le système d'exploitation.
Pour notre exemple de cluster, nous avons le minimum RAM pour un conteneur (yarn.scheduler.minimum-allocation-mb) = 2 Go. Nous allons donc assigner 4 Go pour les conteneurs de tâches de mappage et 8 Go pour les conteneurs de tâches de réduction.
Dans mapred-site.xml:
mapreduce.map.memory.mb
: 4096
mapreduce.reduce.memory.mb
: 8192Chaque conteneur exécutera des machines virtuelles pour les tâches Mapper et Réduire. La taille du segment de mémoire de la machine virtuelle Java doit être définie sur une valeur inférieure à celle de la mémoire de mappage et de réduction définie ci-dessus, afin qu'elles se situent dans les limites de la mémoire du conteneur allouée par YARN.
Dans mapred-site.xml:
mapreduce.map.Java.opts
:-Xmx3072m
mapreduce.reduce.Java.opts
:-Xmx6144m
Les paramètres ci-dessus configurent la limite supérieure de la RAM physique _ que les tâches Mapper et Réduire utiliseront .
Résumer:
mapreduce
, pas ceux mapred
. EDIT: Ce commentaire n'est plus applicable maintenant que vous avez modifié votre question.Java.opts
énumérés ci-dessus.Enfin, vous voudrez peut-être vérifier cet autre SO question qui décrit un problème similaire (et sa solution).
Un contrôle est placé au niveau des fils pour le rapport d'utilisation de la mémoire Vertual et Physique. Le problème n’est pas seulement dû au fait que VM n’a pas suffisamment de mémoire physique. Mais c’est parce que l’utilisation de la mémoire virtuelle est plus importante que prévu pour une mémoire physique donnée.
Remarque : Cela se produit sous Centos/RHEL 6 en raison de son allocation agressive de mémoire virtuelle.
Il peut être résolu soit par:
Désactivez la vérification de l'utilisation de la mémoire virtuelle en définissant yarn.nodemanager.vmem-check-enabled sur false ;
Augmentez le ratio VM: PM en définissant yarn.nodemanager.vmem-pmem-ratio sur une valeur plus élevée.
Références :
https://issues.Apache.org/jira/browse/HADOOP-11364
http://blog.cloudera.com/blog/2014/04/Apache-hadoop-yarn-avoiding-6-time-consuming-gotchas/
Ajouter la propriété suivante dans yarn-site.xml
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
<description>Whether virtual memory limits will be enforced for containers</description>
</property>
<property>
<name>yarn.nodemanager.vmem-pmem-ratio</name>
<value>4</value>
<description>Ratio between virtual memory to physical memory when setting memory limits for containers</description>
</property>
J'ai eu un problème très similaire en utilisant Hive dans EMR. Aucune des solutions existantes ne fonctionnait pour moi - c’est-à-dire qu’aucune des configurations mapreduce ne fonctionnait pour moi; et mettre non plus yarn.nodemanager.vmem-check-enabled
sur false.
Cependant, ce qui a fini par fonctionner a été de définir tez.am.resource.memory.mb
, par exemple:
Hive -hiveconf tez.am.resource.memory.mb=4096
Un autre paramètre à considérer est le yarn.app.mapreduce.am.resource.mb
Je ne peux pas commenter la réponse acceptée en raison de la mauvaise réputation. Cependant, j'aimerais ajouter que ce comportement est voulu par la conception même. NodeManager tue votre conteneur. On dirait que vous essayez d'utiliser le streaming hadoop, qui est exécuté en tant que processus enfant de la tâche de réduction de carte. NodeManager surveille l’ensemble de l’arborescence de processus de la tâche et s’il utilise plus de mémoire que le maximum défini dans mapreduce.map.memory.mb ou mapreduce.reduce.memory.mb, nous nous attendrions à ce que Nodemanager tue la tâche, sinon votre tâche est de voler de la mémoire appartenant à d'autres conteneurs, ce que vous ne voulez pas.
Lorsque je travaillais avec spark dans EMR, j’avais le même problème et la configuration de maximizeResourceAllocation=true
s’est révélée efficace. J'espère que ça aide quelqu'un. Vous devez le définir lorsque vous créez le cluster. À partir du EMR docs:
aws emr create-cluster --release-label emr-5.4.0 --applications Name=Spark \
--instance-type m3.xlarge --instance-count 2 --service-role EMR_DefaultRole --ec2-attributes InstanceProfile=EMR_EC2_DefaultRole --configurations https://s3.amazonaws.com/mybucket/myfolder/myConfig.json
Où myConfig.json devrait dire:
[
{
"Classification": "spark",
"Properties": {
"maximizeResourceAllocation": "true"
}
}
]
Nous avons également fait face à ce problème récemment. Si le problème est lié à la mémoire du mappeur, voici quelques points à vérifier.