重新分区已经有效地分区数据集,以便将小文件组合成更大的文件

Posted

技术标签:

【中文标题】重新分区已经有效地分区数据集,以便将小文件组合成更大的文件【英文标题】:Repartition already partitioned dataset effectively in order to combine small files into bigger ones 【发布时间】:2019-08-15 13:19:30 【问题描述】:

有没有办法重新分区已经分区的数据集,以便有效地减少单个分区中的文件数量,即不洗牌?例如,如果有数据集被一些key分区:

key=1/
  part1
  ..
  partN
key=2/
  part1
  ..
  partN
..
key=M
  part1
  ..
  partN

我可以做到以下几点:

spark.read
  .parquet("/input")
  .repartition("key")
  .write
  .partitionBy("key")
  .parquet("/output")

我希望来自单个分区的所有数据都应该放在同一个执行程序中,但它的工作方式似乎不同,并且涉及很多改组。我在那里做错了吗?数据存储在 Parquet 中,我使用的是 Spark 2.4.3。

【问题讨论】:

【参考方案1】:

您需要在写入之前合并。

val n = 1 //number of desired part files
spark.read
  .parquet("/input")
  .repartition($"key") //requires column
  .coalesce(n)
  .write
  .partitionBy("key")
  .parquet("/output")

【讨论】:

感谢您的建议,但这也会涉及洗牌,性能会更差。 修复触发洗牌,合并不应该。 coalesce 有更少的改组 在合并之前更新了修复的答案,这应该会在正确的分区和所需的部分文件计数中获取所有数据,以便写入不会触发随机播放。

以上是关于重新分区已经有效地分区数据集,以便将小文件组合成更大的文件的主要内容,如果未能解决你的问题,请参考以下文章

如何高效地对大量数据进行分区? [关闭]

PySpark 根据特定列重新分区

没索引oracle无唯一索引交换分区会丢失数据?

SqlServer 分区视图实现水平分表

Kafka集群扩展以及重新分布分区

linux基础9