【问题标题】:Quick file access in a directory with 500,000 files在包含 500,000 个文件的目录中快速访问文件
【发布时间】:2010-09-23 13:07:14
【问题描述】:

我有一个包含 500,000 个文件的目录。我想尽快访问它们。该算法需要我反复打开和关闭它们(不能同时打开 500,000 个文件)。

我怎样才能有效地做到这一点?我原本以为我可以缓存 inode 并以这种方式打开文件,但 *nix 并没有提供通过 inode 打开文件的方法(安全或类似的)。

另一种选择是不要担心它,并希望 FS 在目录中查找文件时做得很好。如果这是最好的选择,那么哪个 FS 效果最好。某些文件名模式是否比其他文件名模式查找得更快?例如 01234.txt 与 foo.txt

顺便说一句,这一切都在 Linux 上。

【问题讨论】:

  • 我在 ext3 上有一个带有 dir_index 的目录,其中包含 100.000 个文件。如果我知道文件名,几乎没有时间损失。如果我在目录上执行“ls”,则需要 3 分钟。之后,所有内容都保留在缓存中,并且在此目录中的操作完全没有时间损失。

标签: c++ linux file-io filesystems inode


【解决方案1】:

假设您的文件系统是ext3,如果启用了 dir_index,您的目录将使用散列 B-Tree 进行索引。这将为您提供尽可能多的提升,就像您可以在应用中编写的任何代码一样。

如果目录被索引,您的文件命名方案应该无关紧要。

http://lonesysadmin.net/2007/08/17/use-dir_index-for-your-new-ext3-filesystems/

【讨论】:

  • 感谢您不走“做子目录”路线
【解决方案2】:

几个想法:

a) 如果您可以控制目录布局,则将文件放入子目录中。

b) 如果您不能移动文件,那么您可能会尝试不同的文件系统,我认为 xfs 可能适合具有大量条目的目录?

【讨论】:

  • 子目录可能会有所帮助。文件系统打开并缓存子目录。一个500K的目录真的很大。 500 个文件的 1000 个目录可能允许更小、更快的目录缓存。
  • +1 表示子目录。使用 ext[23] 单个目录中的文件数量会增加,它会变得非常慢。
【解决方案3】:

如果你有足够的内存,你可以使用 ulimit 来增加你的进程一次可以打开的最大文件数,我已经成功处理了 100,000 个文件,500,000 个应该也可以。

如果这不是您的选择,请尝试确保您的 dentry 缓存有足够的空间来存储所有条目。 dentry 缓存是文件名->inode 映射,内核用来根据文件名来加速文件访问,访问大量不同的文件可以有效地消除dentry 缓存的好处并引入额外的性能损失。 Stock 2.6 内核的哈希值一次最多可包含 256 * MB RAM 条目,如果您有 2GB 内存,则最多可以容纳 500,000 个多一点的文件。

当然,请确保执行适当的分析以确定这是否真的会导致瓶颈。

【讨论】:

    【解决方案4】:

    执行此操作的传统方法是使用散列子目录。假设您的文件名都是均匀分布的哈希,以十六进制编码。然后,您可以根据文件名的前两个字符创建 256 个目录(例如,文件 012345678 将被命名为 01/2345678)。如果一个级别不够,您可以使用两个甚至更多级别。

    只要文件名均匀分布,这将使目录大小保持可控,从而使对它们的任何操作都更快。

    【讨论】:

      【解决方案5】:

      另一个问题是文件中有多少数据? SQL 后端是一种选择吗?

      【讨论】:

      • 我试过 SQL。文件的内容是 ID 和值的排序列表。文件名也是 ID。我使用 SQLite 数据库运行它,仅对文件名 ID 进行创建和索引就需要 26 小时。 SQL 人员建议不要使用数据库,因为我只需要和索引。
      猜你喜欢
      • 2013-06-21
      • 1970-01-01
      • 2015-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-03
      • 2013-06-21
      • 1970-01-01
      相关资源
      最近更新 更多