Настройка Spark На Yarn

Хабр, привет! Вчера на встреча, посвященная Apache Spark , от ребят из Rambler&Co, было довольно много вопросов от участников, связанных с настройкой этого инструмента.

Мы решили пойти по его стопам и поделиться своим опытом.

Тема непростая — поэтому предлагаем вам поделиться своим опытом в комментариях, возможно мы тоже что-то понимаем и используем не так.

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

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

Соответственно, наша задача как организаторов — подготовить кластер к использованию в таком случае.

Особенность нашего использования в том, что количество людей, одновременно работающих над Spark, может быть равно всей группе.

Например, на семинаре, когда все одновременно что-то пробуют и повторяют за нашим преподавателем.

И это немного – иногда до 40 человек.

Вероятно, в мире не так много компаний, которые сталкиваются с таким вариантом использования.

Далее я расскажу, как и почему мы выбрали те или иные параметры конфига.

Начнем с самого начала.

У Spark есть три варианта запуска в кластере: автономный, с использованием Mesos и с использованием YARN. Мы решили выбрать третий вариант, потому что он имел для нас смысл.

У нас уже есть кластер Hadoop. Наши участники уже хорошо знакомы с его архитектурой.

Давайте использовать ПРЯЖУ.

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
   

spark.master=yarn

Дальше интереснее.

Каждый из этих трех вариантов развертывания имеет два варианта развертывания: клиент и кластер.

Основанный на документация и различных ссылок в Интернете, можно сделать вывод, что клиент подходит для интерактивной работы — например, через блокнот Jupyter, а кластер больше подходит для производственных решений.

В нашем случае нас интересовала интерактивная работа, поэтому:

spark.deploy-mode=client

В общем, отныне Spark как-то будет работать на YARN, но нам этого оказалось мало.

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

И тут мы обнаружили интересную вещь — динамическое распределение ресурсов.

Вкратце, суть в следующем: если у вас сложная задача и кластер свободен (например, утром), то использование этой опции Spark может дать вам дополнительные ресурсы.

Потребность там рассчитывается по хитрой формуле.

Не будем вдаваться в подробности — работает хорошо.



spark.dynamicAllocation.enabled=true

Мы установили этот параметр, а при запуске Spark вылетел и не запустился.

Правильно, потому что мне пришлось это прочитать документация более внимательно.

Там написано, что для того, чтобы все было ок, нужно еще включить дополнительный параметр.



spark.shuffle.service.enabled=true

Зачем это нужно? Когда наша работа перестанет требовать так много ресурсов, Spark должен вернуть их в общий пул.

Самый трудоемкий этап практически в любой задаче MapReduce — это этап «Перемешать».

Этот параметр позволяет сохранить данные, сгенерированные на этом этапе, и соответственно освободить исполнителей.

А исполнитель — это процесс, который все рассчитывает на работника.

Он имеет определенное количество ядер процессора и определенный объем памяти.

Этот параметр был добавлен.

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

Но возникла другая проблема — в какой-то момент другие участники проснулись и тоже захотели использовать Spark, но там все было занято, и они были недовольны.

Их можно понять.

Мы начали изучать документацию.

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

Например, если исполнитель находится в режиме ожидания, через какое время у него можно будет забрать ресурсы?

spark.dynamicAllocation.executorIdleTimeout=120s

В нашем случае, если ваши исполнители две минуты ничего не делают, то просьба вернуть их в общий пул.

Но этого параметра не всегда было достаточно.

Было видно, что человек уже давно ничем не занимается, и ресурсы не высвобождаются.

Оказалось, что есть еще специальный параметр — через какое время выбирать исполнители, содержащие кэшированные данные.

По умолчанию этот параметр был бесконечен! Мы это исправили.



spark.dynamicAllocation.cachedExecutorIdleTimeout=600s

То есть, если ваши исполнители 5 минут ничего не делают, отдайте их в общий пул.

В этом режиме скорость освобождения и выдачи ресурсов для большого количества пользователей стала приличной.

Количество недовольства уменьшилось.

Но мы решили пойти дальше и ограничить максимальное количество исполнителей на одну заявку — по сути на одного участника программы.



spark.dynamicAllocation.maxExecutors=19

Сейчас, конечно, на той стороне есть недовольные — «кластер простаивает, а исполнителей у меня всего 19», но что поделаешь? Нам нужен какой-то правильный баланс.

Вы не можете сделать всех счастливыми.

И еще одна небольшая история, связанная со спецификой нашего случая.

Как-то несколько человек опоздали на практическое занятие, и Спарк почему-то к ним не приступил.

Посмотрели количество свободных ресурсов - вроде есть.

Искра должна запуститься.

К счастью, документация к тому моменту уже была где-то в подкорке добавлена, и мы помнили, что при запуске Spark ищет порт, на котором можно запуститься.

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

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

По умолчанию — 16. Это число меньше, чем количество человек в нашей группе в классе.

Соответственно, после 16 попыток Спарк сдался и сказал, что я не могу запуститься.

Мы исправили этот параметр.



spark.port.maxRetries=50

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

Чтобы запустить Spark быстрее, рекомендуется заархивировать папку jars, расположенную в домашнем каталоге SPARK_HOME, и поместить ее в HDFS. Тогда он не будет тратить время на загрузку этих ярников рабочими.



spark.yarn.archive= hdfs:///tmp/spark-archive.zip

Также рекомендуется использовать kryo в качестве сериализатора для более быстрой работы.

Он более оптимизирован, чем стандартный.



spark.serializer=org.apache.spark.serializer.KryoSerializer

А еще есть давняя проблема со Спарком, что он часто вылетает из памяти.

Часто это происходит в тот момент, когда рабочие все рассчитали и отправили результат водителю.

Мы сделали этот параметр для себя больше.

По умолчанию это 1Гб, мы сделали 3.

spark.driver.maxResultSize=3072

И наконец, в качестве десерта.

Как обновить Spark до версии 2.1 в дистрибутиве HortonWorks — HDP 2.5.3.0. Данная версия HDP содержит предустановленную версию 2.0, но мы когда-то для себя решили, что Spark развивается довольно активно, и каждая новая версия исправляет некоторые ошибки плюс предоставляет дополнительные возможности, в том числе для Python API, поэтому решили, что нужно сделай обновление.

Скачал с официального сайта версию для Hadoop 2.7. Разархивировал и положил в папку HDP. Мы установили символические ссылки по мере необходимости.

Запускаем - не запускается.

Пишет очень непонятную ошибку.



java.lang.NoClassDefFoundError: com/sun/jersey/api/client/config/ClientConfig

Погуглив, мы выяснили, что Spark решил не ждать, пока родится Hadoop, а решил использовать новую версию джерси.

Они сами друг с другом спорят на эту тему в JIRA. Решением было скачать майка версия 1.17.1 .

Поместите это в папку jars в SPARK_HOME, снова заархивируйте и загрузите в HDFS. Эту ошибку мы обошли, но возникла новая, довольно упрощенная.



org.apache.spark.SparkException: Yarn application has already ended! It might have been killed or unable to launch application master

При этом пробуем запустить версию 2.0 - все ок.

Попробуйте угадать, что происходит. Мы заглянули в логи этого приложения и увидели примерно следующее:

/usr/hdp/${hdp.version}/hadoop/lib/hadoop-lzo-0.6.0.${hdp.version}.

jar

В общем почему-то hdp.version не разрешилась.

Погуглив, мы нашли решение.

Вам нужно зайти в настройки YARN в Ambari и добавить туда параметр для пользовательского сайта Yarn:

hdp.version=2.5.3.0-37

Эта магия помогла, и Спарк взлетел.

Мы протестировали несколько наших ноутбуков Jupyter. Все работает. Мы готовы к первому уроку Spark в субботу (завтра)! УПД .

В ходе урока выявилась еще одна проблема.

В какой-то момент YARN перестала предоставлять контейнеры для Spark. В YARN пришлось подправить параметр, который по умолчанию был равен 0,2:

yarn.scheduler.capacity.maximum-am-resource-percent=0.8

То есть в распределении ресурсов участвовало только 20% ресурсов.

После изменения параметров мы перезагрузили YARN. Проблема была решена, и остальные участники также смогли запустить искровой контекст. Теги: #spark #apache spark #apache spark #yarn #открытый исходный код #Интеллектуальный анализ данных #Большие данные #Машинное обучение

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.