Должны ли мы избегать partitionBy при записи файлов в S3 в спарк? - PullRequest
0 голосов
/ 15 января 2020

Расположение паркета:

s3://mybucket/ref_id/date/camera_id/parquet-file

Допустим, у меня есть ref_id x3, date x 4, camera_id x 500, если я напишу паркет, как показано ниже (используйте partitionBy) Я получу 3x4x500=6000 файлов, загруженных на S3. Это намного медленнее, чем просто записать пару файлов в ведро верхнего уровня (без многоуровневого префикса)

Какова лучшая практика? Мой коллега утверждает, что partitionBy - это хорошо, когда используется вместе с Hive metastore / table

df.write.mode("overwrite")\
  .partitionBy('ref_id','date','camera_id')\
  .parquet('s3a://mybucket/tmp/test_data')

1 Ответ

1 голос
/ 15 января 2020

Если ваша проблема в слишком большом количестве файлов, что, по-видимому, имеет место, вам необходимо переразметить ваш RDD / dataframe перед тем, как его записать. Каждый раздел RDD / Dataframe генерирует 1 файл на папку.

df.repartition(1)\
 .write.mode("overwrite")\
 .partitionBy('ref_id','date','camera_id')\
 .parquet('s3a://mybucket/tmp/test_data')

В качестве альтернативы repartition вы также можете использовать coalesce.


Если (после переразбиения на 1) файлы слишком малы, вам , необходимо уменьшить структуру каталогов. Документация паркета рекомендует размер файла от 500 МБ до 1 ГБ.

https://parquet.apache.org/documentation/latest/

Мы рекомендуем большие группы строк (512 МБ - 1 ГБ). Поскольку может потребоваться чтение всей группы строк, мы хотим, чтобы она полностью помещалась в одном блоке HDFS.

Если ваши файлы имеют размер несколько Кб или Мб, то у вас есть серьезная проблема, это серьезно плохое выступление.

...