2016-07-22 4 views
1

Я использую искру 1.6.1, и я пытаюсь сохранить dataframe в формате orc.Spark dataframe saveAsTable vs save

Проблема, с которой я сталкиваюсь, заключается в том, что метод сохранения очень медленный, и для каждого исполнителя требуется 50 минут для файла Orc. Это, как я спасая dataframe

dt.write.format("orc").mode("append").partitionBy("dt").save(path) 

Я попытался с помощью saveAsTable к улью таблице, также используя форматы Орков, и это, кажется, быстрее, около 20% до 50% быстрее, но этот способ имеет свои собственные проблемы - кажется, что когда задача не выполняется, повторы всегда будут терпеть неудачу из-за того, что файл уже существует. Это, как я спасая dataframe

dt.write.format("orc").mode("append").partitionBy("dt").saveAsTable(tableName) 

Есть ли причина сохранить метод так медленно? Я что-то не так?

+0

6 минут не так уж медленны для записи 50M файлов. Звучит как много файлов! Насколько велика каждая из них? Сколько исполнителей? Если это один файл в строке, это слишком много. Если они что-то подходят для вашей системы хранения и количество узлов/исполнителей, используемых в типичном запросе, то, возможно, 50 М отлично, но я в этом сомневаюсь. Если каждый из этих 50M файлов равен 1G, то это ~ 47 петабайт, поэтому я сомневаюсь в этом. Если каждый из них 1 МБ, то это 47 терабайт, и я бы предположил, что размер файла слишком мал, чтобы эффективно запрашивать таблицу. Каков общий объем данных? – Davos

+0

это на самом деле 50 мега файлов. – user1960555

+1

нравится, это всего лишь один файл размером 50 МБ? Если это всего лишь один небольшой файл, то не так много разбиения на разделы. Возможно, что ваше поле dt слишком много, и оно создает разделы для каждой строки. Например. если это timestamp/datetime, например, «2017-01-01 14:52:22», тогда кавитация будет происходить каждую секунду, которая затем записывает файл orc для каждого раздела. 50 МБ может быть небольшим файлом, но может быть много строк с разными отметками времени. например если каждая строка ~ 8K, то это ~ 6400 строк, в которых много файлов ввода-вывода. – Davos

ответ

1

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

+0

Мне нужно разбить данные, так что это не вариант. – user1960555

+0

Я думаю, что это действительная точка. Что такое dt? Это подходящий столбец для разбиения? Если мощность очень высока, то это, вероятно, не подходит. Например, если вы используете значение, которое отличается для каждой строки фрейма данных, то это приведет к слишком большому количеству разделов. Накладные расходы на все операции ввода-вывода не стоят. – Davos

1

См. Мои предыдущие комментарии выше относительно мощности и partitionBy.

Если вы действительно хотите, чтобы разбить его, и это только один 50MB файл, а затем использовать что-то вроде

dt.write.format("orc").mode("append").repartition(4).saveAsTable(tableName)

передела создаст 4 примерно даже разделы, а не то, что вы делаете, чтобы разделить на dt, который мог бы записать много файлов орков.

Выбор из 4 разделов немного произволен. Вы не будете получать большую выгоду от производительности/распараллеливания от разбиения крошечных файлов. Накладные расходы на чтение большего количества файлов не стоят того.

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