Ресурсы искры не полностью распределены на Amazon EMR

Я пытаюсь максимизировать использование кластера для простой задачи.

Кластер 1 + 2 x m3.xlarge, runnning Spark 1.3.1, Hadoop 2.4, Amazon AMI 3.7

Задача считывает все строки текстового файла и анализирует их как csv.

Когда я запускаю задачу в качестве режима нитевого кластера, я получаю один из следующих результатов:

  • 0 executor: работа ждет бесконечно, пока я не рунет ее вручную.
  • 1 исполнитель: работа по использованию ресурсов только с 1 машинной работой.
  • OOM, когда я не назначаю достаточно памяти на драйвер

Что я ожидал бы:

  • Драйвер Spark запускается на главном кластере со всей доступной памятью, плюс 2 исполнителя с 9404 МБ каждый (как определено установкой-искры script).

Иногда, когда я получаю "успешное" выполнение с 1 исполнителем, клонирование и перезапуск этапа заканчиваются 0-исполнителем.

Я создал кластер с помощью этой команды:

aws emr --region us-east-1 create-cluster --name "Spark Test"
--ec2-attributes KeyName=mykey 
--ami-version 3.7.0 
--use-default-roles 
--instance-type m3.xlarge 
--instance-count 3 
--log-uri s3://mybucket/logs/ 
--bootstrap-actions Path=s3://support.elasticmapreduce/spark/install-spark,Args=["-x"] 
--steps Name=Sample,Jar=s3://elasticmapreduce/libs/script-runner/script-runner.jar,Args=[/home/hadoop/spark/bin/spark-submit,--master,yarn,--deploy-mode,cluster,--class,my.sample.spark.Sample,s3://mybucket/test/sample_2.10-1.0.0-SNAPSHOT-shaded.jar,s3://mybucket/data/],ActionOnFailure=CONTINUE

С некоторыми изменениями шага, включая:

- память-драйвер 8G -driver-core 4 --num-executors 2


install-spark script с -x создает следующий spark-defaults.conf:

$ cat spark-defaults.conf
spark.eventLog.enabled  false
spark.executor.extraJavaOptions         -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:MaxHeapFreeRatio=70
spark.driver.extraJavaOptions         -Dspark.driver.log.level=INFO
spark.executor.instances        2
spark.executor.cores    4
spark.executor.memory   9404M
spark.default.parallelism       8

Обновление 1

Я получаю такое же поведение с примером JavaWordCount:

/home/hadoop/spark/bin/spark-submit --verbose --master yarn --deploy-mode cluster --driver-memory 8G --class org.apache.spark.examples.JavaWordCount /home/hadoop/spark/lib/spark-examples-1.3.1-hadoop2.4.0.jar s3://mybucket/data/

Однако, если я удалю '-driver-memory 8G', задача получит 2 исполнителя и завершится правильно.

Итак, что случилось с драйвером-памятью, препятствующим моей задаче получить исполнителей?

Если драйвер должен выполняться на главном кластере node вместе с контейнером мастерства пряжи, как описано здесь?

Как я могу предоставить больше памяти моему драйверу искры? (Где собираются и какие-то другие полезные операции)

Ответ 1

Решение максимизировать использование кластера заключается в том, чтобы забыть о параметре "-x" при установке искры на ЭМИ и вручную настроить память исполнителей и ядра.

Этот post дает довольно хорошее объяснение того, как выделяется распределение ресурсов при запуске Spark на YARN.

Важно помнить, что все исполнители должны иметь одинаковые ресурсы! Как мы говорим, Spark не поддерживает гетерогенных исполнителей. (Некоторая работа в настоящее время делается для поддержки графических процессоров, но это еще одна тема)

Итак, чтобы получить максимальную память, выделенную для драйвера, и максимизировав память для исполнителей, я должен разделить мои узлы следующим образом (это slideshare дает хорошие снимки экрана на стр. 25):

  • Node 0 - Мастер (менеджер ресурсов пряжи)
  • Node 1 - NodeManager (Контейнер (драйвер) + контейнер (Исполнитель))
  • Node 2 - NodeManager (Контейнер (Исполнитель) + Контейнер (Исполнитель))

ПРИМЕЧАНИЕ. Еще одна опция: spark-submit с --master yarn --deploy-mode client от мастера node 0. Есть ли какой-либо пример счетчика, это плохая идея?

В моем примере я могу иметь максимум 3 исполнителей из 2-х воколов с 4736 МБ каждый + драйвер с теми же характеристиками.

4736 память выводится из значения yarn.nodemanager.resource.memory-mb, определенного в /home/hadoop/conf/yarn-site.xml. На значении m3.xlarge установлено значение 11520 мб (см. здесь для всех значений, связанных с каждым типом экземпляра)

Тогда получим:

(11520 - 1024)/2 (исполнители на узлы) = 5248 = > 5120 (округляется до 256 мб приращения, как определено в yarn.scheduler.minimum-allocation-mb)

7% * 5120 = 367 округлено до 384 (накладные расходы памяти) станет на 10% в искры 1.4

5120 - 384 = 4736

Другие интересные ссылки:

Ответ 2

Проблема связана с ожиданиями того, как Spark работает на YARN. Когда Spark запускается с режимом развертывания кластера или мастера, установленным в пряжи-кластер, драйвер не выполняется на главном node, а в контейнере Application Master на одном из подчиненных узлов. Подробнее см. https://spark.apache.org/docs/latest/running-on-yarn.html

Я ожидаю, что происходит то, что кластер не может выполнить требования к памяти для драйвера (помните, что на самом деле запрашиваемая память кластера запрашивается плюс дополнительные накладные расходы), и таким образом ждать навсегда, чтобы выделить Мастер приложений, где драйвер будет run или для исполнителей.

Чтобы предоставить драйверу объем памяти, который вы запрашиваете, вам необходимо будет использовать дополнительные ведомые устройства, чтобы одновременно предоставлять ресурсы для кластерного драйвера и исполнителей. С накладными расходами на драйвер, я подозреваю, что вам может понадобиться использовать тип экземпляра с большим объемом памяти. Когда вы запрашиваете 8G для драйвера, загляните в журнал менеджера ресурсов и проверьте требуемую реальную сумму.

Чтобы запустить драйвер на главном node, режим развертывания должен быть клиентом. Это можно сделать с помощью шагов EMR, если вы используете один шаг для вызова script, чтобы локализовать диски-драйверы на главном node, а затем на следующем шаге можно вызвать параметр "исправить-отправить" для клиента режима развертывания и ссылаться на JAR on локальной файловой системы.

Ответ 3

Сообщение Michel Lemay - хорошее чтение фона, и он дает ответ на 1 конкретную конфигурацию кластера. Я встроил эту логику в электронную таблицу, которая покажет лучшие варианты для любого кластера. Чтобы использовать, заполните количество узлов в кластере, количество виртуальных ядер / node и количество выделяемой памяти /node. После этого лист предоставит вам параметры для команд запуска, которые будут полностью использовать ваш кластер для режима клиента и кластера для 1, 2, 4 и 8 исполнителей за node. Я выделил строку, соответствующую двум исполнителям за node, поскольку это всегда было лучшим вариантом в моих тестах. Не стесняйтесь копировать этот лист или добавлять вкладки для разных типов кластеров, как вам нравится.

https://docs.google.com/spreadsheets/d/1VH7Qly308hoRPu5VoLIg0ceolrzen-nBktRFkXHRrY4/edit?usp=sharing

Ответ 4

Вот как я обошел проблему:

Установив spark.executor.memory + память драйвера ниже общего количества любого заданного MASTER node, YARN может разместить как Master, так и исполнителя на заданном node. Вы жертвуете некоторой потерянной памятью на других узлах, но тем более важно, что у меня работают процессоры. Вот пример (на r3.8xlarge):

aws emr add-steps --cluster-id j-1234 --steps Type=Spark,Name=foob3,Args=[--conf,spark.memory.fraction=0.95,--conf,spark.memory.storageFraction=0.1,--conf,spark.yarn.executor.memoryOverhead=8000,--conf,spark.executor.memory=200g,--conf,spark.executor.cores=32,--conf,spark.executor.instances=4,--conf,spark.dynamicAllocation.enabled=false,--class,myclass.Foo,--deploy-mode,cluster,--master,yarn,--driver-memory,10g,s3://myjar-1.0-SNAPSHOT.jar],ActionOnFailure=CONTINUE