5

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

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

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

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

4

5 回答 5

7

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

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

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

于 2008-11-21T22:41:28.793 回答
5

几个想法:

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

b)如果你不能移动文件,那么你可能会尝试不同的文件系统,我认为 xfs 可能对有很多条目的目录有好处?

于 2008-11-21T22:09:20.997 回答
2

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

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

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

于 2008-11-21T22:28:46.277 回答
2

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

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

于 2008-11-21T23:44:02.117 回答
0

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

于 2008-11-21T22:38:52.170 回答