通过 NFS 处理 GB 大小的文件时,如何在 Python 中优化文件 I/O?

Posted

技术标签:

【中文标题】通过 NFS 处理 GB 大小的文件时,如何在 Python 中优化文件 I/O?【英文标题】:How can I optimize file I/O in Python when I process GB-sized files via NFS? 【发布时间】:2020-01-29 03:07:35 【问题描述】:

出于安全考虑,我正在通过 nfs 操作多个文件。由于文件 I/O 速度慢,处理某些事情的情况非常痛苦。以下是对该问题的描述。

我在 Python 中使用 pandas 对数据进行简单处理。所以我经常使用read_csv()to_csv()。 目前,写入一个 10GB 的 csv 文件需要将近 30 分钟,而读取则需要 2 分钟。 我有足够的 CPU 内核(> 20 个内核)和内存(50G~100G)。 很难要求更多带宽。 我需要经常以面向列的方式访问数据。例如,将有 20 列的 100M 记录(其中大部分是数字数据)。对于数据,我经常只读取 3~4 列值的所有 100M 记录。 我尝试过使用 HDF5,但它会构建一个更大的文件并消耗相似的写入时间。而且它不提供面向列的 I/O。所以我放弃了这个选项。 我无法将它们存储在本地。它会违反许多安全标准。实际上我正在使用虚拟机,文件系统是通过 nfs 挂载的。 我反复阅读了几篇专栏文章。对于几列,没有。该任务类似于数据分析。

我可以考虑哪些方法? 在某些情况下,我使用 sqlite3 以简单的方式处理数据并将结果导出到 csv 文件中。我可以在 Python 中使用 sqlite3 来加速 I/O 任务吗?我认为,如果它提供按列操作,那将是一个很好的解决方案。

【问题讨论】:

您是否反复对数据进行进动?您能否在此处理期间将其临时存储在本地磁盘上?目前尚不清楚您将使用 SQLite 做什么,或者为什么您认为它会有所帮助。 @tripleee 感谢您的评论。我已经更新了问题。 如果你不能使用本地存储,那么 SQLite3 可能不会有太大帮助,但如果你正在做重复连接等,内存数据库可能对分析本身很有用。如果你有 10 倍输入文件的内存然后只需读取一次并将其保存在核心中。 @tripleee 非常感谢。但它看起来有点不同的故事。在给定的情况下,内存中的问题实际上并不是一个问题。我可以将所有数据加载到内存中,但问题是文件 I/O 的速度很慢......我想将结果存储在 nfs 上。 使用 NFS 的要求似乎不可协商,如果需要多长时间,那就需要多长时间。 【参考方案1】:

两个选项:pandas hdf5 或 dask。

    您可以使用 format='table' 查看 hdf5 格式。

HDFStore 支持磁盘上的另一种 PyTables 格式,即表格式。 从概念上讲,表格的形状非常像 DataFrame,有行 和列。表可以附加到相同或其他会话中。 此外,还支持删除和查询类型的操作。这 格式由 format='table' 或 format='t' 指定附加或放置 或 to_hdf。

    您可以使用 dask read_csv。它仅在执行()时读取数据

纯粹为了提高 IO 性能,我认为压缩格式的 hdf 是最好的。

【讨论】:

1.我已经尝试过使用 format='table' 的 HDFStore,但根本没有任何改进。 2. 这个解决方案也没有任何效果,因为无论如何它必须逐行遍历每条记录。也许带有压缩的 hdf 是一种选择,但这次我决定不使用它,因为对加速的期望并不那么重要。非常感谢。 当hdf格式为“table”时,可以显着提高I/O性能。对于写入,您可以批量追加而不是一次写入文件。对于读取,您可以选择所需的列或所需的行(如果您将数据列用于所需的列)。 pandas.pydata.org/pandas-docs/stable/user_guide/… 我已经用 'table' 分析了 HDF 的性能。但它几乎没有改善。如果可以将一列附加到 HDFStore 中的现有 DataFrame 中,那就太好了。 ***.com/questions/20428355/… 但是,上面的链接说事实并非如此。您需要认识到面向行和面向列数据结构之间的区别。 write(append) 是基于行的。 read 应该是查询每行或每列的条件。基本上,对于大多数情况应该足够了。基于列的追加是键值数据库解决方案。这不是话题吗?

以上是关于通过 NFS 处理 GB 大小的文件时,如何在 Python 中优化文件 I/O?的主要内容,如果未能解决你的问题,请参考以下文章

在两个 NFS 1Gb/s 文件夹之间移动 9000 万个文件 (270GB) 的最快方式

处理大小超过 1 GB 并通过网络访问的 Access 数据库

在 PHP 中获取大文件(> 2 GB)文件大小的最佳方法? [复制]

运行大小超过 2GB 的 apk 文件时崩溃

Wix:处理大于 2 GB 的文件

批处理 - 特定文件夹的文件大小(以 GB 为单位)的脚本