为什么分区的镶木地板文件会占用更大的磁盘空间?

时间:2019-10-13 05:34:12

标签: python parquet pyarrow

我正在学习使用python和pyarrow制作的实木复合地板文件。镶木地板在压缩和最小化磁盘空间方面表现出色。我的数据集是190MB的csv文件,当另存为snappy压缩的实木复合地板文件时,最终成为单个3MB的文件。

但是,当我将数据集另存为分区文件时,它们的合并大小会更大(61MB)。

这是我要保存的示例数据集:

listing_id |     date     | gender | price
-------------------------------------------
     a     |  2019-01-01  |   M    |   100
     b     |  2019-01-02  |   M    |   100
     c     |  2019-01-03  |   F    |   200
     d     |  2019-01-04  |   F    |   200

当我按日期进行分区(超过300个唯一值)时,分区文件的总大小为61MB。每个文件的大小为168.2kB。 当我按性别分区(2个唯一值)时,分区的文件总共只有3MB。

我想知道镶木地板是否有最小文件大小,以便合并许多小文件会占用更大的磁盘空间?

我的环境:

- OS: Ubuntu 18.04
- Language: Python
- Library: pyarrow, pandas

我的数据集来源:

https://www.kaggle.com/brittabettendorf/berlin-airbnb-data

# I am using calendar_summary.csv as my data from a group of datasets in that link above

我的代码另存为实木复合地板文件:

# write to dataset using parquet
df = pd.read_csv('./calendar_summary.csv')
table = pyarrow.Table.from_pandas(df)
pyarrow.parquet.write_table(table=table, where='./calendar_summary_write_table.parquet')

# parquet filesize
parquet_method1_filesize = os.path.getsize('./calendar_summary_write_table.parquet') / 1000
print('parquet_method1_filesize: %i kB' % parquet_method1_filesize)

我的代码另存为已分区实木复合地板文件:

# write to dataset using parquet (partitioned)
df = pd.read_csv('./calendar_summary.csv')
table = pyarrow.Table.from_pandas(df)
pyarrow.parquet.write_to_dataset(
    table=table, 
    root_path='./calendar_summary/', 
    partition_cols=['date'])

# parquet filesize
import os
print(os.popen('du -sh ./calendar_summary/').read())

1 个答案:

答案 0 :(得分:2)

没有最小文件大小,但是存在存储页脚的开销,并且浪费了通过编码和压缩进行优化的机会。各种编码和压缩都基于这样的想法,即数据具有一定程度的自相似性,可以通过参考较早的相似事件来加以利用。当您将数据拆分为多个文件时,每个文件都需要一个单独的“初始数据点”,连续的文件可以引用该文件,因此磁盘使用率上升。 (请注意,此措词有很大的简化,以避免必须专门采用各种节省空间的技术,但是请参见this answer的一些示例。)

对Parquet文件的大小可能产生巨大影响的另一件事是插入数据的顺序。排序的列可以比随机排序的列更有效地存储。通过对数据进行分区,您可能会无意间更改其排序顺序。另一种可能性是,您可以根据数据的排序属性对数据进行分区,这在将数据存储在单个文件中时可以节省大量空间,并且通过将数据拆分为多个文件而失去了这种机会。最后,您必须记住,Parquet并不是针对存储几千字节的数据而优化的,而是针对几兆字节或几千兆字节(在一个文件中)或几PB的字节(在多个文件中)进行存储的。

如果您想检查数据如何存储在Parquet文件中,则Parquet的Java实现包括parquet-tools实用程序,提供了几个命令。有关构建和入门的信息,请参见其documentation page。各个命令的更详细说明由parquet-tools自己打印。您最感兴趣的命令可能是metadump