python - 在分区日期集上使用 Dask 时 _metadata 文件的重要性
问题描述
我有一个简单的理解,即可以将有关 parquet 数据集中文件的信息放入_metadata
文件中,并用于更有效地创建 parquet Dataset。to_parquet
但是,在将 Dask与append=True
and一起使用时,我遇到了性能问题write_metadata_file=True
,我的完整命令如下。(我还没有完全理解发生了什么,但我的记忆会飙升,就在to_parquet
被拆分给工人之前)。因此,我决定在write_metadata_file=False
没有文件的情况下设置并继续_metadata
,删除之前创建的_metadata
文件。
我发现问题消失了,而且to_parquet
速度也没有变慢,如果有的话,我节省了时间,不必_metadata
每次都写文件。
另外一目了然,当我read_parquet
打开文件时,似乎没有_metadata
文件并没有像我预期的那样导致性能不佳。
我在追加时选择了分区,想知道这是否是_metadata
文件不那么重要的原因,还是不正确?_metadata
是否存在文件重要和不重要的明显情况?
简单的代码示例
dd.to_parquet(df,
engine='fastparquet',
path=uri, storage_options=dl.storage_options,
partition_on=['A', 'B', 'C'],
append=True,
ignore_divisions=True,
write_metadata_file=False)
解决方案
元数据文件提供了三个可能有用的东西:
- 所有组成分区的文件名
- 列块的每个文件中的偏移量
- 每个列块内的值的最小/最大统计信息
- 可以从 _common_metadata 文件或任何一个数据文件中读取数据集的模式。
通过列出文件系统很容易找到其中的第一个,它在本地速度很快,但如果您有数千个文件,远程存储可能会很慢。
第二个是必需的,但可以从每个数据文件的页脚、工作任务和并行读取。因此,如果你没有提前得到它们,你最终会做更多的工作,但可能不会注意到(特别是如果每个部分都有很多行)。与在客户端解析巨大的元数据文件相比,它最终可能会更快。
第三,如果不是从元数据文件中获取,只能通过扫描所有文件的元数据页脚来获取,这可能会非常缓慢并且在客户端单线程完成。但是,如果您不使用这些统计信息进行过滤(gather_statistics=None 或 False),那么您完全可以不用。您仍然可以在没有最大/最小统计信息的情况下过滤分区列。
最后,为了完整性:为什么分区附加元数据很慢?每次追加时都必须重写单个元数据文件,并且它首先需要从每个任务中获取所有元数据片段。我还需要将所有元数据片段保存在内存中。这可能会做得更好,但这是当前的实现。
推荐阅读
- botframework - 将团队中的机器人状态更改为离开
- c++ - 继承类的循环依赖问题
- python - 不使用 pandas 分组
- java - 使用 gson 将 java 对象转换为 json
- python - FacetGrid 中的 lmplot 出现意外的关键字错误
- javascript - 使用 Puppeteer 抓取多个图像 URL
- javascript - 在 nativescript 中渲染 dom 的一部分
- c# - UWP中数据网格的中心列标题
- node.js - 为什么在猫鼬中使用 populate() 时会收到强制转换错误?
- python - 出于某种原因,PyGame 物理模拟所有物体都以相同的速度移动