Linux上的文件/目录的最大数量是多少?

55

我正在开发一个LAMP在线商店,允许管理员为每个商品上传多张图片。

我的担忧是 - 刚开始就会有20000项商品,大约需要60000张图片。

问题:

  1. Linux上的最大文件和/或目录数是多少?

  2. 处理这种情况的常规方式是什么(最佳实践)?

我的想法是为每个商品创建一个基于其唯一ID的目录,但这样仍然会在主“uploads”目录中拥有20000个目录,并且随着旧商品不被删除,它将无限增长。

感谢任何帮助。

6个回答

92

ext[234]文件系统有固定的最大inode数量;每个文件或目录都需要一个inode。您可以使用df -i查看当前计数和限制。例如,在使用默认设置创建的 15GB ext3 文件系统上:

Filesystem           Inodes  IUsed   IFree IUse% Mounted on
/dev/xvda           1933312 134815 1798497    7% /

对于目录的数量,没有特定的限制,但请记住即使是只有一个项目的目录也需要至少一个文件系统块(通常为4KB)。

虽然你可以看到,80000个索引节点不太可能成为问题。并且通过启用tune2fs命令中的dir_index选项,大型目录的查找不会太麻烦。但是,请注意许多管理工具(例如lsrm)在处理文件太多的目录时可能会有困难。因此,建议将文件拆分,以便任何给定目录中不超过几百到一千个项目。一种简单的方法是对使用的ID进行哈希处理,并使用前几个十六进制数字作为中间目录。

例如,假设你有项目ID 12345,并且它的哈希值为'DEADBEEF02842.......'。你可以将文件存储在/storage/root/d/e/12345下。现在,你已经将每个目录中的文件数量减少了1/256。


我知道这是一个旧帖子...但是经过一番搜索,我无法找到合适的东西。是否有一种特定的哈希方法,可以让您期望特定的字母数字字符能够存储在单独的文件夹中? - Jish
4
@Jish 我不明白你的意思。你可以使用任何哈希函数,将其结果转换为十六进制并取前两个十六进制数字。这样,你应该能够在 [0-9a-f] 范围内获得相等的数字分布。 - glglgl
我刚在目录中生成了大约150,000个文件,但是使用“ls myfile*”命令无法列出它们。但是由于我知道文件名,我尝试打开第一个和最后一个文件,成功了。所以我知道这些文件是存在的。 - Chan Kim
在特定情况下,目录数量是没有限制的。但这似乎是不正确的。EXT4 文件系统甚至也有限制,而且我似乎在大约 3500 万个文件时遇到了这个问题。详见:https://www.phoronix.com/news/EXT4-Largedir-Linux-4.13 - Chris Stryczynski

11
如果您的服务器文件系统已经开启了dir_index功能(参见tune2fs(8)以了解如何检查和开启该功能),那么在一个目录中存储超过10万个文件是可以的,直到性能开始下降。(大多数发行版的新文件系统默认都开启了dir_index,因此只有旧文件系统才可能没有默认启用该功能。)
话虽如此,增加另一个目录级别以将目录中的文件数量减少16或256倍,会极大地提高类似于ls *这样的操作的成功几率,并避免超出内核的最大argv大小。
通常,可以通过以下方式完成:
/a/a1111
/a/a1112
...
/b/b1111
...
/c/c6565
...

即,在路径前面加上一个字母或数字,基于一些你可以从名称计算出来的特征。(文件名的md5sumsha1sum的前两个字符是一种常见的方法,但如果你有唯一的对象ID,那么'a'+ id % 16是足够简单的机制来确定使用哪个目录。)


6

60000元不算什么,20000元也是如此。但您应该通过某种方式将这20000元分组,以加快对它们的访问速度。也许可以按100或1000个为一组进行分组,通过取目录号并除以100、500、1000等数字来确定。

例如,我有一个项目,其中文件有编号。我将它们分组为1000个一组,因此我有:

id/1/1332
id/3/3256
id/12/12334
id/350/350934

实际上,您可能会遇到硬限制 - 一些系统具有32位Inode,因此您仅限于每个文件系统的2 ^ 32个数。


1
在默认的mke2fs设置下,您需要几十个TB的磁盘空间才能在inode表中拥有足够的存储空间来容纳2^32个inode :) - bdonlan
4
再等几年,我们就到那里了... :-) - glglgl
7
等待着……事实上我们到了这里。 - Yarek T

4
除了一般性的答案(基本上是“不要那么麻烦”,“调整文件系统”,“使用包含少量文件的子目录组织您的目录”)之外:
如果每个图像很小(例如不到几千字节),则可以将它们放入数据库中(例如使用MySQL作为BLOB)。或者可能在GDBM索引文件中。然后,每个小项目都不会消耗一个inode(在许多文件系统上,每个inode都需要至少一些千字节)。对于某个阈值(例如将大于4kbytes的图像放在单独的文件中,而将较小的图像放在数据库或GDBM文件中),您也可以这样做。当然,不要忘记备份您的数据(并定义备份策略)。

2
这是一种减少磁盘使用的好机制,但会阻止像sendfile(2)这样的零拷贝机制,从而无需进一步的服务器软件干预即可传输文件。 - sarnold

0
年份是2014年。我回到过去来添加这个答案。 有很多大/小文件吗?你可以使用Amazon S3和其他基于Ceph的替代方案,比如DreamObjects,那里没有需要担心的目录限制。
希望这能帮助某人从所有的选择中做出决定。
2023年-6万个文件并不算多。 Linux对能够有效处理的文件数量有限制,这主要涉及到在尝试扫描目录时会遇到的问题,比如复制、移动、重命名等,但通过巧妙地使用find和参数技巧可以克服这些问题。程序员们处理这些限制的方式是使用目录,并通过目录来限制文件的数量,你会在WordPress文件上传中看到这一点。 对于很多文件(10,000++),对象存储仍然是最好的选择。但我曾经管理过使用旧的ext3/4文件系统和目录黑客技巧的图像托管提供商,他们使用了10万多个文件。
在具有ulimit的系统上也会遇到问题,但当你多次遇到并在日志中看到它时,你可以将ulimit增加到任意大小。

我同意这个评论,云计算确实带来了一些新问题,但你必须正确使用它,适合适当的工作类型,而不是抛弃它。


16
啊,多么讽刺......我发现自己专门阅读这个帖子,因为缺乏更好的消费方式,我已经下载了2个月的AWS CloudTrail日志。每天大约有300个json文件。乘以60天。我有大约18,000个文件,并且将它们全部倒入同一个目录中。故事的道理是:现在是2014年,神奇的云服务创造了一堆新问题来替代它们解决的问题。 - David
你可以使用其他能够提供W3C格式日志的CDN提供商。我找到了一堆示例代码并将它们组合起来生成我所需的内容。然后将它们传递给AWStats,例如获取我的统计数据。任何认真对待的程序员都可以做到这一点。可以说,对象存储不是万能的解决方案,但对于上述问题,在2014年它是一个很好的解决方案。 - Abhishek Dujari

-3
md5($id) ==> 0123456789ABCDEF

$file_path = items/012/345/678/9AB/CDE/F.jpg 

1 node = 4096 subnodes (fast)

魔法!它是如此的hacky,我无言以对! - SimplyInk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接