[Hadoop] El contenedor está funcionando más allá de los límites de memoria


Answers

Hay un cheque en el nivel de hilo para la relación de uso de memoria física y vertical. El problema no es solo que la VM no tiene suficiente memoria física. Pero es porque el uso de la memoria virtual es más de lo esperado para la memoria física dada.

Nota : Esto está sucediendo en Centos / RHEL 6 debido a su asignación agresiva de memoria virtual.

Se puede resolver ya sea por:

  1. Deshabilite la verificación de uso de la memoria virtual configurando yarn.nodemanager.vmem-check-enabled en false ;

  2. Aumente la relación VM: PM estableciendo yarn.nodemanager.vmem-pmem-ratio en algún valor más alto.

Referencias

https://issues.apache.org/jira/browse/HADOOP-11364

blog.cloudera.com/blog/2014/04/…

Agregue la siguiente propiedad en 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>
Question

En Hadoop v1, he asignado cada 7 mapper y slot reductor con tamaño de 1GB, mis mapeadores y reductores funcionan bien. Mi máquina tiene memoria 8G, 8 procesadores. Ahora con YARN, cuando ejecuto la misma aplicación en la misma máquina, recibo un error de contenedor. Por defecto, tengo esta configuración:

  <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>

Me dio error:

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.

Luego intenté establecer el límite de memoria en 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>

Pero aún recibo un error:

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.

Estoy confundido por qué la tarea del mapa necesita tanta memoria. Según entiendo, 1GB de memoria es suficiente para mi tarea de mapa / reducir. ¿Por qué cuando asigno más memoria al contenedor, la tarea usa más? ¿Es porque cada tarea obtiene más divisiones? Creo que es más eficiente disminuir un poco el tamaño del contenedor y crear más contenedores, de modo que se ejecutan más tareas en paralelo. El problema es: ¿cómo puedo asegurarme de que a cada contenedor no se le asignarán más divisiones de las que puede manejar?




También enfrentamos este problema recientemente. Si el problema está relacionado con la memoria del mapeador, hay algunas cosas que me gustaría sugerir que deben verificarse.

  • Compruebe si el combinador está habilitado o no ? Si es así, significa que la lógica de reducción debe ejecutarse en todos los registros (salida del asignador). Esto sucede en la memoria. Según su aplicación, debe verificar si el combinador habilitante ayuda o no. El intercambio es entre los bytes de transferencia de red y el tiempo empleado / memoria / CPU para la lógica de reducción en el número de registros 'X'.
    • Si siente que el combinador no tiene mucho valor, simplemente deshabilítelo.
    • Si necesita un combinador y 'X' es un número enorme (digamos millones de registros) entonces considerando cambiar su lógica de división (para los formatos de entrada predeterminados use menos tamaño de bloque, normalmente 1 tamaño de bloque = 1 división) para asignar menos cantidad de registros a un solo mapeador.
  • Número de registros que se procesan en un solo mapeador. Recuerde que todos estos registros deben estar ordenados en la memoria (la salida del mapeador está ordenada). Considere establecer mapreduce.task.io.sort.mb (por defecto es 200MB) a un valor mayor si es necesario. mapred-configs.xml
  • Si alguno de los anteriores no fue de ayuda, intente ejecutar la lógica del correlacionador como una aplicación independiente y perfilar la aplicación usando un Analizador (como JProfiler) y ver dónde se usa la memoria. Esto puede darte muy buenas ideas.



No puedo comentar sobre la respuesta aceptada, debido a la baja reputación. Sin embargo, me gustaría agregar, este comportamiento es por diseño. El NodeManager está matando a su contenedor. Parece que está intentando usar la transmisión de hadoop que se ejecuta como un proceso secundario de la tarea de reducción de mapa. El NodeManager supervisa todo el árbol de procesos de la tarea y si consume más memoria que el máximo establecido en mapreduce.map.memory.mb o mapreduce.reduce.memory.mb respectivamente, esperaríamos que el administrador de nodos elimine la tarea, de lo contrario su tarea es robar la memoria perteneciente a otros contenedores, que no desea.