ext4 将文件单独放入子目录 VS 一个大目录

ext4 将文件单独放入子目录 VS 一个大目录

与将文件全部存储在单个大目录中相比,将文件组织到子文件夹中是否会提高 ext4 文件系统上的读取访问性能?

目前,我们有一个包含 600K 文件(每个 3-10 MB)的大目录。如果我们将这些文件组织到子文件夹中,每个子文件夹包含 5K 文件,性能是否会有所提高?

您能否建议一些工具来执行此类基准测试?

作为附加信息,我们通过按完整路径读取这些文件并将新文件写入目录来使用这些文件。此外,我们阅读新创建的文件比旧文件更频繁

答案1

每个 3-10 MB

文件大小并不重要。

与将文件全部存储在单个大目录中相比,将文件组织到子文件夹中是否会提高 ext4 文件系统上的读取访问性能?

从逻辑上讲,这取决于您对“性能”的含义:如果您需要列出全部文件,然后将它们放在子目录中会更糟糕。如果您知道要查看哪个子目录,并且只需要列出该子目录,那么可能会更快。

有趣的情况是,当您只需要按名称访问文件,而不需要获取目录列表时:

目前,我们有一个包含 600K 文件(每个 3-10 MB)的大目录。如果我们将这些文件组织到子文件夹中,每个子文件夹包含 5K 文件,性能是否会有所提高?

同样,取决于您的使用模式!看来您很少列出目录,因此差异不会很大。

从目录获取文件的工作原理大致如下:

  1. 路径被分解为组件 ( /path/to/file-> path, to, file)
  2. 对于每个目录,需要询问包含目录的索引(因此,为了能够查看,您需要在的索引中to查找;要获取 ,您需要在 的索引中查找,为此您首先需要已经抬头看了。topathfilefiletotopath

显然,路径越深,查找就越多,这需要一些时间。

问题是:从 -files 索引查找条目是否N比对索引进行两次连续查找花费更多时间sqrt(N)? (因此,在这种情况下,您将N文件放入sqrt(N)目录中,sqrt(N)每个目录都有条目。)

答案是:不。 Ext4的使用B树索引,这意味着目录项查找的优化实现log[N]在第一种情况下需要时间,并且2·log[sqrt(N)] = 2·log[N^(1/2)] = 2·(1/2)·log[N] = log[N]是渐近的。

当然,翻看数据结构通常是很多就数据局部性而言更可取,特别是如果这保证您永远不必返回存储来读取“更深”目录的索引。因此,就查找时间而言,单个大目录将胜过许多较小的目录。

这很重要吗?我对此表示怀疑。 600,000 个文件并不算多。

然而,如果您的应用程序是智能的,情况会有所不同:如果您仅打开所有目录描述符一次(供以后使用openat),并将它们的结构保留在您的应用程序中,那么当然您只需研究较小的指数即可受益。请注意,如果您知道您肯定会再次读取文件,那么保持文件描述符打开并将其存储在某种内部表中一段时间​​可能是明智之举。这重要的open花费的部分时间可能不是在目录查找上,而是在您和close文件时发生的上下文切换上。

答案2

它是极其在一个目录中包含数百个以上的文件是不明智的。

  • 由于中断等原因导致的文件系统错误可能会出现全部文件暂时或永久无法访问。
  • 文件系统缓存将被所有条目提前污染。
  • 由于生成所有条目(包括列表和搜索操作)的大量数据和内核工作,多个操作将永远无法完成。

我什至不确定您的用例是否需要 FS 存储。您可能可以考虑数据库,包括 NoSQL。

相关内容