【问题标题】:Maximum number of files/directories on Linux?Linux 上的最大文件/目录数?
【发布时间】:2012-01-04 13:09:54
【问题描述】:

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

我担心的是 - 马上就会有 20000 个项目,这意味着大约 60000 张图像。

问题:

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

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

我的想法是根据每个项目的唯一 ID 为每个项目创建一个目录,但是我在主 uploads 目录中仍然有 20000 个目录,并且它会像旧项目一样无限增长不会被删除。

感谢您的帮助。

【问题讨论】:

    标签: linux directory directory-structure


    【解决方案1】:

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

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

    除此之外,对目录没有限制;请记住,每个文件或目录至少需要一个文件系统块(通常为 4KB),即使它是一个只有一个项目的目录。

    不过,正如您所见,80,000 个 inode 不太可能成为问题。使用dir_index 选项(可通过tune2fs 启用),在大型目录中查找并不是什么大不了的事。但是,请注意,许多管理工具(例如lsrm)可能很难处理其中包含太多文件的目录。因此,建议将文件拆分,这样在任何给定目录中的项目都不会超过几百到一千个。一个简单的方法是对您使用的任何 ID 进行哈希处理,并将前几个十六进制数字用作中间目录。

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

    【讨论】:

    • 我知道这是一篇旧帖子......但经过一番挖掘后无法找到像样的东西。是否有特定的散列方法可以让您期望特定的字母数字字符能够将它们存储在单独的文件夹中?
    • @Jish 我不明白你。您可以使用任何散列函数,将其结果转换为十六进制并取前两个十六进制数字。然后,理想情况下,两个数字的 [0-9a-f] 之间的分布是相等的。
    • 我刚刚在目录中生成了大约 150,000 个文件,但是 ls 命令无法使用 ls myfile* 命令列出它们。但是因为我知道我尝试过的文件名,所以我可以打开第一个和最后一个文件。所以我知道文件存在。
    【解决方案2】:

    如果您的服务器文件系统启用了dir_index 功能(有关检查和启用该功能的详细信息,请参阅tune2fs(8)),那么您可以合理地在一个目录中存储超过100,000 个文件,以免性能下降。 (dir_index 多年来一直是大多数发行版的新文件系统的默认设置,因此它只是一个 old 文件系统,默认情况下没有启用该功能。)

    也就是说,添加另一个目录级别以将目录中的文件数量减少 16 或 256 倍将大大提高 ls * 之类的工作机会,而不会超出内核的最大 argv 大小。

    通常,这是通过以下方式完成的:

    /a/a1111
    /a/a1112
    ...
    /b/b1111
    ...
    /c/c6565
    ...
    

    即,在路径前添加一个字母或数字,基于您可以计算名称的某些功能。 (文件名的前两个字符md5sumsha1sum 是一种常见的方法,但如果您有唯一的对象ID,那么'a'+ id % 16 是很容易确定使用哪个目录的机制。)

    【讨论】:

      【解决方案3】:

      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。

      【讨论】:

      • 在默认的 mke2fs 设置中,您需要几十 TB 的磁盘空间才能在 inode 表中为 2^32 个 inode 提供足够的空间:)
      • 等几年,我们就在那里...... :-)
      • 等待......我们确实到了
      【解决方案4】:

      除了一般的答案(基本上“不要打扰那么多”、“调整你的文件系统”和“用包含几千个文件的子目录来组织你的目录”):

      如果单个图像很小(例如小于几千字节),您也可以将它们放在数据库中(例如,使用 MySQL 作为 BLOB)或者可能放在 @987654322 中,而不是将它们放在文件夹中@ 索引文件。然后每个小项目不会消耗一个 inode(在许多文件系统上,每个 inode 至少需要一些千字节)。您也可以对某些阈值执行此操作(例如,将大于 4kbytes 的图像放在单个文件中,将较小的图像放在数据库或 GDBM 文件中)。当然,不要忘记备份您的数据(并定义备份策略)。

      【讨论】:

      • 这是一种减少磁盘使用的好机制,但会阻止诸如 sendfile(2) 之类的零拷贝机制在没有进一步服务器软件干预的情况下传输文件。
      【解决方案5】:

      今年是 2014 年。我及时回来补充这个答案。 很多大/小文件?您可以使用 Amazon S3 和其他基于 Ceph 的替代方案,例如 DreamObjects,无需担心目录限制。

      我希望这可以帮助某人从所有备选方案中做出决定。

      【讨论】:

      • 具有讽刺意味的是......我发现自己正在阅读这个线程,因为我已经下载了 2 个月的 AWS CloudTrail 日志,因为没有更好的方式来使用它们。每天似乎有大约 300 个 json 文件。乘以 60 天。我有大约 18,000 个文件,我将它们全部转储到同一个目录中。故事的寓意:这一年是 2014 年,神奇的云服务创造了一堆新问题来取代他们解决的问题。
      • 您可以使用其他可以提供 W3C 格式日志的 CDN 提供商。我找到了一堆示例代码并将它们组合起来生成我需要的东西。然后将它们传递给 AWStats,例如以获取我的统计信息。任何认真的程序员都可以做到这一点。可以说对象存储不是灵丹妙药,但对于上面提到的问题,它是 2014 年的一个很好的解决方案
      【解决方案6】:
      md5($id) ==> 0123456789ABCDEF
      
      $file_path = items/012/345/678/9AB/CDE/F.jpg 
      
      1 node = 4096 subnodes (fast)
      

      【讨论】:

      • 神奇!太老套了,我说不出话来!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 2021-12-13
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 2021-11-21
      • 2012-06-09
      相关资源
      最近更新 更多