现代文件系统中数百万文件的性能影响是什么?

假设我们使用ext4(启用了dir_index)来托pipe3M文件(平均大小为750KB),我们需要决定我们要使用的文件夹scheme。

在第一种解决scheme中 ,我们将散列函数应用于文件,并使用两个级别文件夹(第一级为1个字符,第二级为2个字符):因此,作为filex.for散列等于abcde1234 ,我们将其存储on / path / a / bc /abcde1234-filex.for。

第二种解决scheme中 ,我们将散列函数应用于文件,并使用两个级别文件夹(第一级为2个字符,第二级为2个字符):因此,作为filex.for散列等于abcde1234 ,我们将其存储on / path / ab / de /abcde1234-filex.for。

对于第一个解决scheme,我们将有以下scheme/path/[16 folders]/[256 folders]每个文件夹 (文件所在的最后一个文件夹) 平均为732个文件

在第二种解决scheme中,我们将拥有/path/[256 folders]/[256 folders]每个文件夹平均文件数为45个

考虑到我们要从这个scheme中写很多(基本上是nginxcaching系统)的文件( 但大多是读取 ),从性能的angular度来看,如果我们select了一个或其他的解决scheme呢?

另外,我们可以使用什么工具来检查/testing这个设置?

创build这种目录结构的原因是文件系统必须在目录中定位文件,而目录越大,操作越慢。

慢多less取决于文件系统的devise。

ext4文件系统使用B树来存储目录条目。 对这个表的查询预计会花费O(log n)时间,大部分时间都小于ext3和以前的文件系统使用的天真的线性表(如果不是,那么目录对于它来说太小了真的很重要)。

XFS文件系统使用B +树来代替。 这比散列表或B树的优点是,任何节点可能有多个子节点b ,其中XFS中的变化可能高达254(或19根节点,这些数字可能已过时)。 这给你一个O(log b n)的时间复杂度,这是一个巨大的改进。

这些文件系统中的任何一个都可以处理单个目录中的数以万计的文件,XFS在具有相同数量的inode的目录上比ext4快得多。 但是你可能不想要一个带有3M inode的目录,因为即使是B +树,查找也需要一些时间。 这就是导致以这种方式创build目录的原因。

至于你提出的结构,你给出的第一个选项正是在nginx例子中显示的。 它可以在任何一个文件系统上运行,尽pipeXFS仍然有一些优势。 第二个选项可能会稍微好一点,也可能稍差,但即使在基准testing中,它也可能会非常接近。

根据我的经验,其中一个缩放因子是给定散列名称分区策略的inode的大小。

两个build议的选项都会为每个创build的文件创build最多三个inode条目。 此外,732个文件将创build一个仍然比通常的16KB小的inode。 对我而言,这意味着任一选项都会执行相同的操作。

我为你的短小散列表示赞赏。 以前的系统我已经采取了给定文件的sha1sum和基于该string拼接目录,一个更难的问题。

当然,这两个选项都有助于将目录中的文件数量减less到xfs或ext4或任何文件系统的合理值。 哪一个更好,不得不testing说明。

与您的应用程序模拟真实工作负载的基准是理想的。 否则,拿出一些专门模拟许多小文件的东西。 说到这一点, 这里有一个叫做smallfile的开源软件 。 其文档引用了其他一些工具。

hdparm做持续的I / O是没有用的。 它不会显示与很多文件关联的许多小I / O或巨型目录条目。

其中一个问题是扫描文件夹的方式。

想象一下在文件夹上运行扫描的Java方法。

在JVM很短的时间内,它将不得不分配大量的内存并释放它。

最好的方法是安排文件夹结构的方式,每个文件是在专用文件夹,例如年/月/日。

全扫描完成的方式是每个文件夹有一个函数运行,所以JVM将退出函数,释放RAM并在另一个文件夹上再次运行。

这只是一个例子,但无论如何,有这么大的文件夹是没有意义的。