Spark dataframe write метод записи многих небольших файлов

У меня есть довольно простая работа, покрывающая файлы журналов на паркет. Он обрабатывает 1,1 ТБ данных (разделенных на 64Мб - 128МБ файлов - наш размер блока составляет 128МБ), что составляет около 12 тысяч файлов.

работа работает следующим образом:

 val events = spark.sparkContext
  .textFile(s"$stream/$sourcetype")
  .map(_.split(" || ").toList)
  .collect{case List(date, y, "Event") => MyEvent(date, y, "Event")}
  .toDF()

df.write.mode(SaveMode.Append).partitionBy("date").parquet(s"$path")

он собирает события с общей схемой, преобразует в фрейм данных, а затем записывает как паркет.

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

В идеале я хочу создать только несколько паркетных файлов в разделе "дата".

каков был бы лучший способ контролировать это? Это с помощью ' coalesce ()'?

как это повлияет на количество файлов, созданных в данном разделе? Это зависит от того, сколько исполнителей у меня работает в Искра? (в настоящее время-100).

3 ответов


вы должны repartiton свой DataFrame чтобы соответствовать разбиению DataFrameWriter

попробуйте это:

df
.repartition($"date")
.write.mode(SaveMode.Append)
.partitionBy("date")
.parquet(s"$path")

самым простым решением было бы заменить фактическое разделение на:

df
 .repartition(to_date($"date"))
 .write.mode(SaveMode.Append)
 .parquet(s"$path")

вы также можете использовать более точные разметки DataFrame i.e день и, возможно, час часового диапазона. и тогда вы можете быть менее точными для писателя. Это зависит от объема данных.

вы можете уменьшить энтропию разбиения DataFrame и предложение write with partition by.


я столкнулся с той же проблемой, и я мог бы использовать coalesce решить мою проблему.


df
  .coalesce(3) // number of parts/files 
  .write.mode(SaveMode.Append)
  .parquet(s"$path")

для получения дополнительной информации об использовании coalesce или repartition вы можете обратиться к следующим spark: объединение или передел