OutOfMemoryError в драйвере Spark - дамп кучи 1 ГБ, хотя настроено 10 ГБ

У меня есть 100% воспроизводимое OutOfMemoryError (чаще всего из-за превышения лимита накладных расходов GC) при запуске моего приложения Spark. Это происходит примерно на 700-м этапе.

Поскольку стек ошибок всегда включает такие классы, как .ui., TaskSchedulerImpl и т. д., я пришел к выводу, что проблема заключается не в исполнителях, а в самом процессе-драйвере. Этот вывод подтверждается следующим наблюдением: за несколько минут до OOM вывод stdout начинает приостанавливаться на секунду или около того, печатая множество строк сразу после паузы.

spark.driver.memory настроен на 10 ГБ, но используемые инструменты отладки показывают, что драйвер использует только 1 ГБ:

  1. I've used these great instructions on collecting GC statistics and analyzing it with the gceasy.io service; it clearly showed that:
    • The maximum heap usage after GC is approximately 1Gb.
    • Ближе к моменту OOM график «использования кучи» почти достигает максимума в 1Gb, и многочисленные события GC не влияют на это. GC overhead limit exceeded в лучшем виде.
  2. I've used the MAT to analyse the heap dump created immediately after the OutOfMemoryError.
    • The heap dump contains approximately the same 1Gb of data.
    • Дерево доминаторов показывает, что более половины его потребляется объектами пользовательского интерфейса.

Этот вопрос ответ предполагает, что библиотеки JNI могут использовать 10Gb-1Gb=9Gb; но, по-видимому, Spark не использует это в своей основе; я тоже.

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

Кроме того, мне не удалось найти объяснения модели памяти драйвера Spark.

Вопрос в следующем: как мне сохранить данные отладки пользовательского интерфейса и не столкнуться с OOM в моем драйвере?


person Matvey Zhuravel    schedule 14.08.2019    source источник


Ответы (1)


Реальная проблема заключалась в том, что процесс драйвера использовал только 1 ГБ памяти, несмотря на настройку spark.driver.memory=10G.

Согласно документации: в режиме клиента эта конфигурация< /strong> (spark.driver.memory) нельзя задавать через SparkConf непосредственно в вашем приложении, потому что в этот момент драйвер JVM уже запущен. Вместо этого установите это с помощью параметра командной строки --driver-memory или в файле свойств по умолчанию.

Я использовал клиентский режим. Перемещение параметра из параметра контекста Spark в параметр командной строки spark-submit решило проблему.

P.S. "Если ничего не работает как положено, читайте инструкцию" (с).

person Matvey Zhuravel    schedule 16.08.2019