Контейнер работает за пределами памяти


в Hadoop v1 я назначил каждый слот 7 mapper и reducer размером 1 ГБ, мои mappers & reducers работают нормально. Моя машина имеет память 8G, процессор 8. Теперь с YARN, при запуске того же приложения на той же машине, я получил ошибку контейнера. По умолчанию у меня есть такие настройки:

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

это дало мне ошибку:

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.

затем я попытался установить ограничение памяти в 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>

но все равно получаю ошибку:

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.

Я смущает, почему задача карты требует столько памяти. В моем понимании, 1 ГБ памяти достаточно для моей задачи map/reduce. Почему, когда я назначаю больше памяти контейнеру, задача использует больше? Это потому, что каждая задача получает больше разбивает? Я считаю, что более эффективно немного уменьшить размер контейнера и создать больше контейнеров, чтобы больше задач выполнялось параллельно. Проблема в том, как я могу убедиться, что каждому контейнеру не будет назначено больше расщеплений, чем он может обрабатывать?

6 62

6 ответов:

вы также должны правильно настроить максимальное выделение памяти для MapReduce. От этот учебник HortonWorks:

[...]

каждая машина в нашем кластере имеет 48 ГБ оперативной памяти. Часть этой оперативной памяти должна быть > зарезервирована для использования операционной системой. На каждом узле мы назначим 40 ГБ ОЗУ для > YARN для использования и сохраним 8 ГБ для операционной системы

для нашего примера кластера, у нас есть минимальная оперативная память для контейнера (пряжа.планировщик.minimum-allocation-mb) = 2 ГБ. Таким образом, мы назначим 4 ГБ для контейнеров задач Map и 8 ГБ для контейнеров Reduce tasks.

в mapred-сайте.XML-код:

mapreduce.map.memory.mb: 4096

mapreduce.reduce.memory.mb: 8192

каждый контейнер будет запускать виртуальные машины для задач map и reduce. виртуальная машина Java размер кучи должен быть установлен ниже, чем на карте и уменьшить память определено выше, так что они находятся в пределах контейнера память, выделенная ПРЯЖА.

в mapred-сайте.XML-код:

mapreduce.map.java.opts:-Xmx3072m

mapreduce.reduce.java.opts:-Xmx6144m

вышеуказанные настройки настройка верхнего предела физической оперативной памяти, что Карта и уменьшить задачи будут использовать.

в итоге:

  1. в пряжи, вы должны использовать mapreduce configs, а не mapred те. EDIT: этот комментарий больше не применим теперь, когда вы отредактировал ваш вопрос.
  2. то, что вы настраиваете на самом деле, сколько вы хотите запросить, а не то, что Макс выделить.
  3. максимальные пределы установлены с java.opts параметры, перечисленные выше.

наконец, вы можете проверить это другое поэтому вопрос это описывает аналогичную проблему (и решение).

проверка помещенная на уровне пряжи для коэффициента использования вертикальной и физической памяти. Проблема не только в том, что VM не имеет достаточной физической памяти. Но это потому, что использование виртуальной памяти больше, чем ожидалось для данной физической памяти.

Примечание: это происходит на Centos / RHEL 6 из-за его агрессивного выделения виртуальной памяти.

Она может быть решена путем :

  1. отключить проверку использования виртуальной памяти установочный пряжа.nodemanager.vmem-check-enabled до ложные;

  2. увеличить коэффициент VM:PM, установив пряжа.nodemanager.vmem-pmem-ratio к некоторому более высокому значению.

ссылки :

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

http://blog.cloudera.com/blog/2014/04/apache-hadoop-yarn-avoiding-6-time-consuming-gotchas/

добавьте следующее свойство в 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>

у меня была очень похожая проблема с использованием HIVE в EMR. Ни одно из существующих решений не работало для меня - т. е. ни одна из конфигураций mapreduce не работала для меня; и ни одна из настроек yarn.nodemanager.vmem-check-enabled значение false.

однако то, что в конечном итоге работало, было настройкой tez.am.resource.memory.mb, например:

hive -hiveconf tez.am.resource.memory.mb=4096

еще один параметр для рассмотрения настройки является yarn.app.mapreduce.am.resource.mb

Я не могу прокомментировать принятый ответ, из-за низкой репутации. Тем не менее, я хотел бы добавить, что это поведение по дизайну. NodeManager-это убийство вашего контейнера. Похоже, вы пытаетесь использовать потоковую передачу hadoop, которая выполняется как дочерний процесс задачи map-reduce. NodeManager отслеживает все дерево процессов задачи и если он съедает больше памяти, чем максимальный набор в mapreduce.карта.память.Мб или mapreduce.уменьшить.память.МБ соответственно, мы ожидали бы Nodemanager убить задачу, в противном случае ваша задача кражи памяти, принадлежащей другим контейнерам, которые вы не хотите.

во время работы с spark в EMR у меня была такая же проблема и настройка maximizeResourceAllocation=true сделал трюк; надеюсь, что это поможет кому-то. Вы должны установить его при создании кластера. Из 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

где myConfig.JSON должен сказать:

[
  {
    "Classification": "spark",
    "Properties": {
      "maximizeResourceAllocation": "true"
    }
  }
]

мы также столкнулись с этой проблемой в последнее время. Если проблема связана с памятью mapper, я хотел бы предложить несколько вещей, которые необходимо проверить.

  • проверить, если combiner включен или нет? Если да, то это означает, что логика reduce должна выполняться на всех записях (вывод mapper). это происходит в памяти. на основе вашего приложения вам нужно проверить, помогает ли включение объединителя или нет. Компромисс заключается между байтами сетевой передачи и время, затраченное/память / процессор для логики уменьшения на " X " количество записей.
    • Если вы чувствуете, что комбайнер не имеет большого значения, просто отключите его.
    • Если вам нужен комбайнер, а " X " - это огромное количество (скажем, миллионы записей), то с учетом изменения логики разделения (для входных форматов по умолчанию используется меньший размер блока, обычно 1 размер блока = 1 сплит) для отображения меньшего количества записей в одном сопоставителе.
  • количество записей, обрабатываемых в a один картограф. Помните, что все эти записи должны быть отсортированы в (вывод картографа отсортирован). Рассмотрите возможность установки mapreduce.task.io.sort.mb (по умолчанию 200 Мб) на более высокое значение, если это необходимо. mapred-configs.xml
  • Если что-либо из вышеперечисленного не помогло, попробуйте запустить логику mapper как отдельное приложение и профилировать приложение с помощью профилировщика (например, JProfiler) и посмотреть, где используется память. Это может дать вам очень лучшее понимание.