2017-01-22 2 views
3

Я запускаю приложение Spark в режиме YARN-client с шестью исполнителями (каждый из четырех ядер и памяти исполнителей = 6 ГБ и надстройки = 4 ГБ, версия искры: 1.6.3/2.1.0).Использование физической памяти продолжает увеличиваться для приложения Spark на YARN

Я нахожу, что память моего исполнителя продолжает расти до тех пор, пока не будет убит диспетчер узлов; и он выдает информацию, которая говорит мне увеличить spark.yarn.excutor.memoryOverhead.

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

FYI, логика моего приложения довольно проста. Это означает объединение небольших файлов, сгенерированных за один день (один каталог за один день), в один и запись в HDFS. Вот код ядра:

val df = spark.read.parquet(originpath) 
       .filter(s"m = ${ts.month} AND d = ${ts.day}") 
       .coalesce(400) 
val dropDF = df.drop("hh").drop("mm").drop("mode").drop("y").drop("m").drop("d") 

dropDF.repartition(1).write 
     .mode(SaveMode.ErrorIfExists) 
     .parquet(targetpath) 

Исходный файл может содержать раздел от сотни до тысяч уровней. И общий паркетный файл составляет от 1 до 5   ГБ.

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

В любом случае, я сам поступил по этому вопросу. В какой-то статье говорится, что она находится в прямой буферной памяти (я не ставил себя).

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

Кроме того, я считаю, один человек на Stack Overflow   с очень похожей ситуации: Ever increasing physical memory for a Spark application in YARN

Этот парень утверждал, что это ошибка с паркетом, но комментарий под сомнение его. Люди в этом списке почт могут также получить по электронной почте часы назад от blondowski который описал эту проблему при написании JSON: Executors - running out of memory

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

Я надеюсь, что кто-то, у кого есть опыт в этой проблеме, может объяснить это. Почему это происходит и что является надежным способом решения этой проблемы?

+0

Начну с того, что 'repartition (1)' и/или 'coalesce (1)' в основном являются анти-шаблонами в Spark, если ваши данные не очень малы, тогда вы можете собрать результат, записать его в обычном манера. – eliasah

+0

@eliasah Есть ли еще один эффективный способ выполнить мою комбинированную работу? –

+0

Зачем вам нужно положить все в один файл паркета? – eliasah

ответ

1

Я просто делаю некоторое расследование в эти дни с моим коллегой. Вот моя мысль: из искры 1.2 мы используем Netty с памятью для кучи памяти, чтобы уменьшить GC во время перетасовки и передачи кеша. В моем случае, если я попытаюсь увеличить объем памяти слишком большой. Я получу исключение Max buffer buffer. Когда Netty блокирует передачу, по умолчанию будет пять потоков, чтобы захватить блок данных для целевого исполнителя. В моей ситуации один кусок слишком большой, чтобы вписаться в буфер. Так что gc здесь не поможет. Моим окончательным решением является сделать еще один передел до передела (1). Просто сделать в 10 раз больше разделов, чем оригиналов. Таким образом, я могу уменьшить размер каждой передачи Netty. Таким образом, я, наконец, это сделаю.

Также я хочу сказать, что это не лучший выбор для переделки большого набора данных в один файл. Этот чрезвычайно несбалансированный сценарий - это отбросы ваших вычислительных ресурсов.

Добро пожаловать в любой комментарий, я до сих пор не понимаю эту часть.

Смежные вопросы