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


30

假设我们正在使用ext4(启用dir_index)来托管大约3M文件(平均大小为750KB),并且我们需要确定要使用的文件夹方案。

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

第二个解决方案中,我们对文件应用哈希函数,并使用两个级别的文件夹(第一级为2个字符,第二级为2个字符):因此,作为filex.for哈希值等于abcde1234,我们将其存储在/ path中/ ab / de /abcde1234-filex.for。

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

而在第二个解决方案,我们将有/path/[256 folders]/[256 folders]平均每个文件夹45页的文件

考虑到我们将大量(基本上是nginx缓存系统)从该方案中写入/取消链接/读取文件(但大部分是read),从性能的角度来说,如果我们选择一种或其他解决方案,它是否很重要?

另外,我们可以使用哪些工具来检查/测试此设置?


7
显然,基准测试会有所帮助。但是ext4可能是错误的文件系统。我正在看XFS。
ewwhite

4
我不会只看 XFS,我会立即使用它,而无需费劲。B +树每次都击败哈希表。
迈克尔·汉普顿

感谢您提供的技巧,虽然我尝试这样做,hdparm -Tt /dev/hdX但基准测试有点困难,但它可能不是最合适的工具。
leandro moreira

2
hdparm不是正确的工具,它是对块设备原始性能的检查,而不是对文件系统的测试。
HBruijn

Answers:


28

之所以会创建这种目录结构,是因为文件系统必须在目录中找到文件,并且目录越大,该操作越慢。

慢多少取决于文件系统设计。

ext4文件系统使用B树来存储目录条目。在此表上进行查找预计将花费O(log n)时间,大部分时间少于ext3和以前的文件系统使用的朴素线性表(如果不是,则目录太小了,无法进行查找)非常重要)。

XFS文件系统使用B +树代替。与哈希表或B树相比,此方法的优势在于,任何节点都可以具有多个子节点b,其中在XFS中b可以变化,并且可以高达254(对于根节点,则为19;并且这些数字可能已过时) )。这使您的时间复杂度为O(log b n),这是一个很大的改进。

这些文件系统中的任何一个都可以在一个目录中处理数万个文件,而XFS的速度明显快于inode数量相同的目录中的ext4。但是您可能不希望使用3M索引节点的单个目录,因为即使使用B +树,查找也可能需要一些时间。这就是导致首先以这种方式创建目录的原因。

至于建议的结构,您给出的第一个选项正是nginx示例中显示的内容。尽管XFS仍然有一些优势,但它在任一文件系统上都将表现良好。第二个选项的性能可能会稍好一些或稍差一些,但即使在基准测试中,也可能非常接近。


对于XFS或ext4,放置文件系统的硬件将对性能产生巨大影响。速度较慢的5400-rpm SATA驱动器每秒可以执行约50次随机IO操作,好的15,000-rpm SAS驱动器每秒可以进行几百次,而SSD可能会受到带宽限制,并且可能每秒获得数百万次随机IO操作。如果不是更多。
安德鲁·亨利

1
严格来说,固定$ b $的$ O(\ log_b n)$与$ O(\ log n)$的复杂度相同。但是对于OP来说,实际常数很重要。
哈根·冯·埃岑

除非我的文件系统有问题,否则ext4无法在单个目录中处理10,000个文件。做一个简单的ls -l需要一分钟,如果该目录已经脱落了inode缓存。并且当它被缓存时,它仍然需要一秒钟的时间。这是在流量相对较低的Web服务器上配备的SSD和Xeon带有大量RAM的。
阿披·贝克特

@AbhiBeckert是从ext3升级的吗?如果是这样,请尝试建立一个新目录并将文件移动到该目录。
迈克尔·汉普顿

@Hampton号。这是(相当)最近在现代硬件上设置的服务器。我一直在与我们的sysadmin /数据中心一起解决这个问题,已经有几个月了。我们每月要支付数千美元来租用服务器,但服务器性能却无法令人满意。看起来唯一的选择是移动到新的目录结构-也许使用哈希代替文件名的日期来更均匀地分布它。
阿披·贝克特

5

根据我的经验,缩放因子之一是给定哈希名称分区策略的索引节点的大小。

建议的两个选项都为每个创建的文件最多创建三个inode条目。另外,732个文件将创建一个仍小于通常的16KB的索引节点。对我来说,这意味着任何一个选项都将执行相同的操作。

我为您的简短发言鼓掌;我以前使用的以前的系统采用给定文件的sha1sum并基于该字符串拼接目录,这是一个更困难的问题。


1
是什么使SHA1和(及其他更长的哈希和)的使用“更难解决”?对人类用户而言,这是一件很麻烦的事情,但是对于OS,文件系统和其他程序来说,都是一样的。
kbolino

4

当然,对于xfs或ext4或任何文件系统,这两个选项均有助于将目录中的文件数量减少到合理的水平。尚不清楚哪个更好,必须进行测试才能知道。

应用程序进行基准测试(模拟实际工作量)是理想的选择。否则,提出一些可以专门模拟许多小文件的工具。谈到这一点,这是一个称为smallfile的开源程序。其文档引用了其他一些工具。

hdparm进行持续的I / O没什么用。它不会显示与许多文件关联的许多小型I / O或巨型目录条目。


1

问题之一是扫描文件夹的方法。

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

它必须分配大量的内存,并在短时间内取消分配,这对于JVM来说非常繁重。

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

完全扫描的方式是,对于每个文件夹都运行一次该函数,因此JVM将退出该函数,释放RAM,然后在另一个文件夹上再次运行它。

这仅仅是示例,但是无论如何拥有如此大的文件夹是没有意义的。


2
您假设使用Java并扫描文件夹。这个问题都没有提到,除了扫描它外,还有其他方法可以用Java处理该文件夹。
user207421 '16

1

我一直遇到同样的问题。试图在ext4的Ubuntu服务器中存储数百万个文件。结束了运行自己的基准测试。发现平面目录在使用更简单的同时性能更好:

基准

写了一篇文章


那绝对不是预期的结果。在继续使用或推荐它之前,您应该更深入地了解为何获得此意外结果。
迈克尔·汉普顿
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.