Python:数百万个小文件的读写速度慢

Ben*_*tal 14 python io file

结论: 似乎HDF5是我的目的.基本上" HDF5是用于存储和管理数据的数据模型,库和文件格式. "并且旨在处理大量数据.它有一个名为python-tables的Python模块.(链接在下面的答案中)

HDF5在节省数吨和大量数据方面完成了1000%的工作.从2亿行读取/修改数据虽然很痛苦,但这是下一个要解决的问题.


我正在构建具有大量子目录和文件的目录树.大约有1000万个文件分布在十万个目录中.每个文件都在32个子目录下.

我有一个python脚本,可以构建这个文件系统并读取和写入这些文件.问题是当我达到一百多万个文件时,读写方法变得非常慢.

这是我的函数,它读取文件的内容(文件包含一个整数字符串),向其添加一定数量,然后将其写回原始文件.

def addInFile(path, scoreToAdd):
    num = scoreToAdd
    try:
        shutil.copyfile(path, '/tmp/tmp.txt')
        fp = open('/tmp/tmp.txt', 'r')
        num += int(fp.readlines()[0])
        fp.close()
    except:
        pass
    fp = open('/tmp/tmp.txt', 'w')
    fp.write(str(num))
    fp.close()
    shutil.copyfile('/tmp/tmp.txt', path)
Run Code Online (Sandbox Code Playgroud)
  • 关系数据库对于访问这些数据似乎太慢了,所以我选择了一种文件系统方法.
  • 我之前尝试过为这些执行linux控制台命令,但速度要慢一些.
  • 我首先将文件复制到临时文件然后访问/修改它然后将其复制回来,因为我发现这比直接访问文件更快.
  • 将所有文件放入1个目录(采用reiserfs格式)会导致访问文件时速度过慢.

我认为减速的原因是因为有大量的文件.执行此功能1000次,时间不到一秒......但现在达到1分钟.

你怎么建议我解决这个问题?我是否更改了目录树结构?

我只需要快速访问这个庞大的文件池中的每个文件*

ear*_*arl 6

两个建议:

首先,涉及子目录的32深度嵌套的结构本质上是有缺陷的.假设您确实拥有"大约1000万个文件",那么一个级别的子目录应该是足够的(假设您使用的是现代文件系统).

第二:你说你有"大约1000万个文件",每个文件"包含一个整数字符串".假设它们是32位整数并且您直接存储它们而不是字符串,这相当于总数据集大小为40MiB(10M文件*每个文件4个字节).假设每个文件名长度为32个字节,则为此数据添加另一个320MiB的"密钥".

因此,您将能够轻松地将整个数据集放入内存中.我建议这样做,并对主存储器中保存的数据进行操作.除非有任何理由需要精心设计的目录结构,否则我建议将数据存储在一个文件中.

  • 根据所使用的文件系统,一级子目录可能会遇到麻烦.并非所有文件系统都能很好地处理目录中的数千个文件. (2认同)

小智 6

我知道这不是你问题的直接答案,但它是你问题的直接解决方案.

你需要使用像HDF5这样的东西进行研究.它仅适用于具有数百万个别数据点的分层数据类型.

你真的很幸运,因为有很棒的Python绑定HDF5称为pytables.我以非常相似的方式使用它并取得了巨大的成功.


Mad*_*ist 5

我建议你重新考虑一下你的方法,使用大量极小的文件肯定会给你带来严重的性能问题.根据程序的目的,某种数据库可能更有效率.

如果您正在进行大量I/O操作,您还可以在问题上投入更多硬件并使用SSD或将所有数据保存在RAM中(显式或通过缓存).仅使用硬盘驱动器,您就无法在这种情况下获得良好的性能.

我从来没有使用它,但是例如Redis是一个持久的键值存储,应该非常快.如果你的数据符合这个模型,我肯定会尝试这个或类似的东西.您将在本文中找到一些性能数据,这些数据可以让您了解可以达到的速度.