【问题标题】:How to efficiently write multiple pyarrow tables (>1,000 tables) to a partitioned parquet dataset?如何有效地将多个 pyarrow 表(>1,000 个表)写入分区 parquet 数据集?
【发布时间】:2021-05-09 10:33:03
【问题描述】:

我有一些其他格式的大文件(总共约 7,000 个,每个 4GB),我想使用 pyarrow.parquet.write_to_dataset() 将它们存储到分区(hive)目录中以进行快速查询。

目前,我正在使用以下过程遍历所有文件:

import pyarrow as pa
import pyarrow.parquet as pq

for each_file in file_list:
    ndarray_temp = reader(each_file)
    table_temp = pa.Table.from_arrays(ndarray_temp)
    pq.write_to_dataset(table_temp, root_path='xxx', partition_cols=[...])

这非常慢,因为 pq.write_to_dataset() 大约需要 27 秒才能将每个表写入目录(在 SSD 上),并且它会在每个文件夹下创建许多小 parquet 文件。

我的问题是:

  1. 有没有更好的方法呢?假设我有足够的内存来保存 100 个临时表,我可以一次写这 100 个表吗?

  2. 每个文件夹下数百个parquet小文件会不会影响读取和过滤性能?是一张一张写很多小表好还是一次写一张大表好?

非常感谢!

T

【问题讨论】:

    标签: python hive parquet large-files pyarrow


    【解决方案1】:

    回答您的问题:

    1. 这是一个有点自以为是的问题,它不太适合堆栈溢出。你的方法还不错,因为这种类型的工作越简单越好。如果您想通过并行处理多个文件来加快这种类型的工作流程,我建议您使用 dask 或 luigi 之类的框架。

    2. 假设您的源文件是分区列的随机样本,那么对于您加载并保存到 parquet 的每个文件,每个分区中都会有一个新的 parquet 文件。因此,每个分区最终可能会拥有多达 7000 个镶木地板文件。这是因为write_to_dataset 每次调用时都会向每个分区添加一个新文件(而不是附加到现有文件)。这会对性能产生负面影响。如果您发现这是个问题,您可以对数据集进行“碎片整理”。为此,您将一个一个地加载分区并将它们保存到一个新的数据集中。然后您将拥有一个每个分区只有一个文件的数据集。

    【讨论】:

    • 谢谢你的回答,我想我没有很好地描述我的第一个问题。我试图询问是否应该连接来自多个文件的多个数组,然后只执行一个 write_table。我现在做了一些测试,似乎这不是一个显着的改进。非常感谢第二个问题的建议,效果很好。
    猜你喜欢
    • 2021-03-26
    • 2020-03-08
    • 2020-12-10
    • 1970-01-01
    • 2019-02-06
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多