Планирование Spark в приложении: проблема с производительностью - PullRequest
4 голосов
/ 02 марта 2020

Я реализую Apache Spark Планирование в вот так (Scala code):

// group into list of 10 items...
val maxSimultaneousSubmitAndMonitorThreadsInDriver = 10

// ... in order to throttle the number of threads submitting and monitoring apps at a time
val lists = myList grouped maxSimultaneousThreadsInDriver 

for (aList <- lists) {

   // pick a list, then convert it to Scala Parallel list
   aList.par.foreach { // so 10 threads MAX at a time, that can handle job submission and monitoring
      case (file_name) => {

        // in each driver thread, create different Spark session
        val sparkChild = sparkMain.newSession()

        // then do specific stuff with such session
        val childDF = sparkChild.read.parquet( filename + "_directory/*.parquet") 
        ...
     }
   }

}

Итак, как вы знаете, с концепцией Планирование в такой экземпляр одного драйвера может контролировать несколько приложений Spark. поэтому У меня может быть несколько приложений Spark, которые запускаются одновременно . (В моем случае каждое приложение Spark может затем выполнять очень специфические c задачи на чтение файла, основываясь на имени, в зависимости от бизнес-правил).

Планировщик по умолчанию настроен в режиме FIFO:

По умолчанию планировщик Spark выполняет задания в режиме FIFO. Каждое задание делится на «этапы» (например, сопоставление и уменьшение фаз), и первое задание получает приоритет над всеми доступными ресурсами, в то время как его этапы имеют задачи для запуска, затем второе задание получает приоритет, например c. Если заданиям, находящимся в начале очереди, не нужно использовать весь кластер, более поздние задания могут начать выполняться сразу же [...]

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

With Spark Scheduling Within mode, cluster resources seems clearly underutilized

Это противоположность классическим приложениям Spark, которые у меня естественным образом полностью загружают ЦП почти все время!

Итак, мой последний вопрос, как оптимизировать производительность Планирование искры в пределах ?

Что я пробовал:

  • изменение maxSimultaneousSubmitAndMonitorThreadsInDriver, чтобы регулировать число потоков, которые отправляют и отслеживают приложение в данный момент времени
  • пытается увеличить spark.scheduler.listenerbus.eventqueue.capacity
  • пытается увеличить / уменьшить spark.default.parallelism
  • пытается увеличить / уменьшить spark.sql.shuffle.partitions

Если я увеличу количество потоков, которые могут одновременно отправлять и отслеживать приложения Spark (с помощью системы управления газом), я получаю OOM.

Относительно spark.default.parallelism и spark.sql.shuffle.partitions, я не знаю, как выбрать соответствующее значение. Если я НЕ Планирование в (только с одним приложением на драйвер), то значение, которое я установлю, вероятно, будет 192 (число ядер), чтобы иметь хорошие результаты.

Но с Планирование в пределах неясно. Каждое представленное задание является небольшим, и параллелизм 192 для каждого задания кажется излишним (и медленным?) ..

Любая информация будет принята с благодарностью

1 Ответ

1 голос
/ 10 марта 2020

Сначала вы определяете maxSimultaneousSubmitAndMonitorThreadsInDriver=10, а затем используете maxSimultaneousThreadsInDriver вместо того, который вы только что объявили, это умышленно?

Во-вторых, попробуйте удалить строку val sparkChild = sparkMain.newSession() и вместо нее изменить следующую строку на val childDF = sparkMain.read.parquet( filename + "_directory/*.parquet"), она компилируется? если это так, оставьте это и проверьте снова.

Вы пытались увеличить количество исполнителей?
Добавить или изменить, если параметр уже существует в вашей искровой отправке, до --num-executors 20, если для создания контекста по коду добавьте conf.set("spark.executor.instances", 20) прямо перед new SparkContext(conf) строка в вашем коде.
Теперь запустите снова, это увеличивает производительность? если этого недостаточно, увеличьте до 40.
Если вы все еще застряли, продолжайте читать.

Поведение при запуске задания Spark по умолчанию - FIFO, т. Е. Первое задание будет иметь приоритет, а последующее будет выполнено только при наличии доступных ресурсов после , когда первое задание освободило ресурсы.
Я предполагаю, что вы получаете только 14 задач (по 7 в каждом исполнителе), потому что ваши файлы очень малы, если задачи выполняются довольно быстро, так что перераспределение не решит проблему, но разрешит параллельные задания.
Поскольку вы ищете параллелизм между вашими заданиями, я бы предложил вам использовать планировщик FAIR и назначать разные пулы для каждого потока / задания, которое вы создаете.

Сконфигурируйте общий ресурс FAIR для своего приложения spark, добавив в свой spark-submit --conf spark.scheduler.mode=FAIR, если при создании контекста по коду добавьте conf.set("spark.scheduler.mode", FAIR) прямо перед строкой new SparkContext(conf) в вашем коде.

Назначьте случайное имя пула перед выполнением любого задания в вашем потоке (вы можете взять идентификатор потока, но даже для одного и того же потока рекомендуются разные имена пулов для каждого задания):

val randomString = scala.util.Random.alphanumeric.take(10).mkString("")
sparkMaster.setLocalProperty("spark.scheduler.pool", randomString)
val childDF = sparkMaster.read.parquet( filename + "_directory/*.parquet") 

сейчас общий ресурс FAIR должен равномерно распределить ресурсы между потоками.
Если вы все еще наблюдаете низкое использование ядер, попробуйте максимально увеличить максимальный объем пула потоков без использования OOM.
, если он все еще медленный рассмотрите перераспределение на (max_cores / max_threads), в вашем случае (видел 2 исполнителей с 192 доступными ядрами, то есть всего 384 384/10=38, так что перераспределение (38) может помочь.

Ссылка: https://spark.apache.org/docs/latest/job-scheduling.html#scheduling - в-в-приложения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...