ext4 中深层嵌套文件夹的“成本”是多少?

Mar*_*tin 11 filesystems ext4 directory-structure

当我需要进行某些通配符匹配时,我遇到了单个目录中数十万个文件的性能问题。从我的应用程序的角度来看,一个简单的解决方案是将文件放在深度嵌套的文件夹中。

整个层次结构中文件夹总数的预期上限为 9^30。可以假设永远不会达到这个限制(见下面的评论)。文件夹的数量只会随着文件的添加而增加。

问题:当在 ext4 文件系统上创建大量文件夹时,从文件系统的角度来看是否有任何影响?例如消耗了多少空间。一个文件夹只包含另一个文件夹?我会因为元数据过多而遇到麻烦吗?

(从我的应用程序的角度来看,与更简单的层次结构中的基于哈希的文件夹相比,上述结构具有某些优势,我知道组织数据的“更好”方法)

Hau*_*ing 8

每个文件夹消耗一个 inode(256 字节)和至少一个块(可能是 4096 字节)。更大的问题可能是多个层次结构层的访问时间。

性能问题可能不是由于文件夹大小,而是由于路径名扩展。路径名扩展有两个问题:

  1. 它对结果(不能被禁用)进行排序,这对于大量项目需要很长的时间。
  2. 它创建(取决于使用类型)非法命令行(项目太多)。

您应该在应用程序级别解决这个问题。一次读取 100 个文件名(未排序,使用findls -U)并在必要时对这些小组进行排序。这也允许并行读取磁盘和 CPU 使用率。

如果您确实需要路径名扩展和/或排序,那么您可以通过将文件按排序顺序添加到它们的(空)目录中来大大加快进程(如果文件很少更改)。


Gil*_*il' 8

与以前的版本相比,Ext4 在大目录中的处理能力要好一些,但在同一目录中包含 10,000 个左右的文件后仍然陷入困境。将目录层次结构中的文件分离出几级深是保持性能的常见解决方案。查找文件时,每个深度增量都需要额外的间接寻址,但宽度随深度呈指数增长。

例如,如果您的文件名称仅由字母、数字和一些标点符号组成,则不要将它们全部放在同一目录中,而是根据文件名的前两个字符创建子目录。也就是说,文件foobar存储在fo/foobar. 如果子目录中的文件仍然太多,请增加深度:fo/ob/foobar,依此类推。您必须进行基准测试才能确定要拆分的字符数以及停止的深度。

有很多潜在的目录,大多数最终都会是空的。因此,与其在开始时创建所有目录,不如按需创建它们。例如,如果您需要创建文件foobar,则fo如果该目录不存在则创建该目录,然后对 执行相同操作fo/ba,然后将其存储foobarfo/ba/foobar.

除非文件很小(小于 4kB),否则目录的空间量可以忽略不计。即使是很小的文件,只要你不过度使用深度,目录也会比文件少得多。但是,如果您有大量小文件,则表明您应该改用数据库。