Объедините несколько необработанных файлов в один паркетный файл

У меня есть большое количество событий, разделенных yyyy / mm / dd / hh в S3. Каждый раздел содержит около 80 000 необработанных текстовых файлов. Каждый необработанный файл содержит около 1.000 событий в формате JSON.

Когда я запускаю сценарий для преобразования:

datasource0 = glueContext.create_dynamic_frame.from_catalog(database=from_database,
                                                                table_name=from_table,
                                                                transformation_ctx="datasource0")
map0 = Map.apply(frame=datasource0, f=extract_data)
applymapping1 = ApplyMapping.apply(......)
applymapping1.toDF().write.mode('append').parquet(output_bucket, partitionBy=['year', 'month', 'day', 'hour'])

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

part-00000-a5aa817d-482c-47d0-b804-81d793d3ac88.snappy.parquet
part-00001-a5aa817d-482c-47d0-b804-81d793d3ac88.snappy.parquet
part-00002-a5aa817d-482c-47d0-b804-81d793d3ac88.snappy.parquet

Каждый из них имеет размер 1-3 КБ. Число примерно соответствует количеству имеющихся у меня необработанных файлов.

У меня сложилось впечатление, что Glue берет все события из каталога, разбивает их так, как я хочу, и хранит в одном файле для каждого раздела.

Как мне этого добиться?


person Dusan Vasiljevic    schedule 06.11.2017    source источник


Ответы (1)


Вам просто нужно установить repartition(1), который перетасует данные со всех разделов в один раздел, который будет генерировать один выходной файл во время записи.

applymapping1.toDF()
             .repartition(1)
             .write
             .mode('append')
             .parquet(output_bucket, partitionBy=['year', 'month', 'day', 'hour'])
person Sahil Desai    schedule 07.11.2017
comment
Спасибо! После небольшого чтения я думаю, что coalesce, возможно, более уместно. Есть предположения? - person Dusan Vasiljevic; 07.11.2017
comment
coalesce (1) и repartition (1) одинаковы по функциональности, поскольку все данные должны быть переданы в один раздел, должно быть перемешивание, и оно будет одинаковым для обеих операций, - person Sahil Desai; 08.11.2017
comment
Я знаю, что это старый поток ... но для всех прохожих ... хотя, похоже, с той же функциональностью, я неоднократно обнаруживал, что coalesce (1) не работает с крупномасштабными данными, и прибегал к repartition (1), если я действительно нужен единый файл. - person Renée; 29.03.2019
comment
@ Renée Это потому, что повторное разделение заставит другое перемешивание (и, следовательно, этап) изменить параллелизм (количество разделов, переходящих в дополнительный добавленный этап). С другой стороны, coalesce изменяет параллелизм в восходящем направлении (количество разделов, переходящих в текущий этап); таким образом, любые преобразования данных на этапе, содержащем объединение, уменьшили бы параллелизм. Что происходит быстрее между повторным разделением и объединением, зависит от выполняемых данных и этапов обработки (т. Е. Дополнительное перемешивание из-за повторного разделения может быть узким местом). Комментарий Сахила неверен. - person TaylerJones; 25.08.2019
comment
Я не думаю, что repartition (1) сделает то, о чем просят create a single file per partition. repartition (1) создаст 1 раздел, а не один файл на раздел. - person dres; 02.03.2020