拥有一个大的镶木地板文件还是拥有许多较小的镶木地板文件更好?

Posted

技术标签:

【中文标题】拥有一个大的镶木地板文件还是拥有许多较小的镶木地板文件更好?【英文标题】:Is it better to have one large parquet file or lots of smaller parquet files? 【发布时间】:2017-08-12 14:53:09 【问题描述】:

我了解 hdfs 会将文件拆分为 64mb 的块。我们有流式传输的数据,我们可以将它们存储到大文件或中型文件中。列文件存储的最佳大小是多少?如果我可以将文件存储到最小列为 64mb 的位置,是否会比拥有 1gb 文件节省任何计算时间?

【问题讨论】:

【参考方案1】:

注意 Parquet 文件在内部被拆分为 row groups

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

因此,如果您的基线 parquet 文件不小/很小,通过使 parquet 文件更大,行组仍然可以相同。处理没有巨大的直接损失,但相反,如果您的镶木地板文件较小/很小,读者有更多机会利用也许更大/更优化的行组,例如行组不能跨越多个镶木地板文件。

此外,较大的 parquet 文件不会限制读取器的并行性,因为每个 parquet 文件可以在逻辑上分解为多个 splits(由一个或多个行组组成)。

较大 parquet 文件的唯一缺点是创建它们需要更多内存。因此,您可以注意是否需要增加 Spark 执行器的内存。

row groups 是 Parquet 文件进行垂直分区的一种方式。每个row group 都有许多行块(每列一个,一种为镶木地板中的数据集提供水平分区的方法)。

【讨论】:

【参考方案2】:

目标是每个文件大约 1GB(spark 分区)(1)。

理想情况下,您应该使用 snappy 压缩(默认),因为 snappy 压缩 parquet 文件是可拆分的 (2)。

使用 snappy 代替 gzip 会显着增加文件大小,因此如果存储空间是一个问题,则需要考虑。

.option("compression", "gzip") 是覆盖默认快速压缩的选项。

如果您需要调整数据集/数据帧/RDD 的大小/重新分区,请调用.coalesce(<num_partitions> 或最坏情况下的.repartition(<num_partitions>) 函数。警告:特别是重新分区但也合并可能会导致数据重新洗牌,因此请谨慎使用。

此外,parquet 文件大小以及所有文件的大小通常应大于 HDFS 块大小(默认 128MB)。

1) https://forums.databricks.com/questions/101/what-is-an-optimal-size-for-file-partitions-using.html 2)http://boristyukin.com/is-snappy-compressed-parquet-file-splittable/

【讨论】:

我们正在使用带有 hive 上下文的合并函数和 50 个执行程序来处理我们的一个文件,该文件约为 15GB,运行起来就像一个魅力。 @garren-s 您需要使用 snappy 来让您的 parquet 文件可拆分的资格不是必需的,无论使用何种压缩方式,parquet 文件总是可拆分的,只要它们足够大以包含多个RowGroups(文件中分区的拼花名称)。您引用的文章有一个误导性的标题,但文章的文本和它下面的后续 cmets 确实阐明了所有使用镶木地板的压缩类型为您提供了可拆分的文件。然而,除非您使用像 snappy 这样的流式压缩,否则 CSV 文件确实是不可拆分的。

以上是关于拥有一个大的镶木地板文件还是拥有许多较小的镶木地板文件更好?的主要内容,如果未能解决你的问题,请参考以下文章

附加时的镶木地板文件保护

读取列中具有混合数据类型的镶木地板文件

Pyspark:从不同的目录加载类似的镶木地板,并将文件夹名称作为一列组合成一个 DataFrame [重复]

如何在读取前根据定义的模式读取 pyspark 中的镶木地板文件?

即使存在与之关联的镶木地板文件,Hive 外部表也不显示任何数据

AWS Spectrum 为 AWS Glue 生成的镶木地板文件提供空白结果