在同一个Linux目录中有数百或数千个文件可以(性能方面)吗?

时间:2012-01-05 00:01:01

标签: linux performance filesystems

众所周知,在Windows中,当您尝试打开其中一个文件时,文件太多的目录会产生糟糕的性能。我有一个程序只能在Linux上执行(目前它在Debian-Lenny上,但我不想具体说明这个发行版)并将许多文件写入同一目录(它有点像存储库)。 “很多”我的意思是每天数十个,这意味着一年后我希望有5000-10000个文件。它们是要保留的(一旦创建文件,它永远不会被删除)并且假设硬盘具有所需的容量(如果没有,则应该升级)。这些文件的大小范围很广,从几KB到几十MB(但不多于此)。名称始终是数值,以递增方式生成。 我担心长期性能下降,所以我会问:

  • 将所有内容写入同一目录是否可以?或者我应该考虑为每个X文件创建一组子目录?
  • 我是否需要将特定文件系统用于此类目录?
  • 什么是更强大的替代方案?专业文件系统?哪个?
  • 任何其他考虑/推荐?

6 个答案:

答案 0 :(得分:11)

这在很大程度上取决于文件系统。

ext2和ext3每个目录的硬限制为32,000个文件。这比你要问的要多一些,但足够接近我不会冒险。此外,每次在目录中按名称访问文件时,ext2和ext3都将执行线性扫描。

据说ext4可以解决这些问题,但我不能亲自担保。

XFS从一开始就是为这类事物而设计的,即使你把数百万个文件放在目录中也能很好地工作。

因此,如果您真的需要大量文件,我会使用XFS或者ext4。

请注意,如果您拥有大量文件(除非您使用“ls -f”),没有文件系统会使“ls”快速运行,因为“ls”将读取整个目录并对名称进行排序。几万个可能不是什么大不了的事,但是一个好的设计应该超出你认为你需要的第一眼......

对于您描述的应用程序,我可能会创建一个层次结构,因为对于看到它的人来说几乎不需要任何额外的编码或脑力劳动。具体来说,您可以将您的第一个文件命名为“00/00/01”而不是“000001”。

答案 1 :(得分:5)

如果您使用没有目录索引的文件系统,那么在一个目录中包含大量文件(例如,> 5000)是一个非常糟糕的主意。

但是,如果你有目录索引(默认情况下在ext3中更新的发行版上启用),那么这不是一个问题。

然而,它确实打破了很多工具,在一个目录中有很多文件(例如,“ls”将stat()所有文件,这需要很长时间)。您可以轻松地将其拆分为子目录。

但不要过分。不要不必要地使用许多级别的嵌套子目录,这只是使用大量的inode并使元数据操作变慢。

我见过更多“嵌套目录级别太多”的情况,而不是“每个目录中文件太多”。

答案 2 :(得分:3)

我拥有的最佳解决方案(而不是引用微文件系统基准测试中的某些值)是自己测试。

只需使用您选择的文件系统即可。为100,1000和10000条目创建一些随机测试数据。然后,测量系统执行时间关注的操作所需的时间(打开文件,读取100个随机文件等)。

然后,您比较时间并使用最佳解决方案(将它们全部放入一个目录;将每年放入一个新目录;将每年的每个月放入一个新目录中)。

我不知道你在使用什么,但创建一个目录是一次(可能很简单)操作,那么为什么不这样做而不是改变文件系统或尝试其他更耗时的东西?< / p>

答案 3 :(得分:1)

除了其他答案之外,如果庞大的目录由已知的应用程序或库管理,您可以考虑用其他东西替换它,例如:

  • 一个GDBM索引文件; GDBM是一个非常常见的库,提供索引文件,它将任意键(一个字节序列)与任意值(另一个字节序列)相关联。
  • 可能是MySQL或PostGresQL等数据库中的表。注意索引。
  • 其他一些索引数据的方法

上述方法的优点包括:

  1. 大量小物品的空间性能(每个小于1千字节)。文件系统需要每个项目的inode。索引系统的粒度可能要小得多
  2. 时间表现:您不会访问每个项目的文件系统
  3. 可伸缩性:索引方法旨在满足大量需求:GDBM索引文件或数据库可以处理数百万个项目。我不确定您的目录方法是否可以轻松扩展。
  4. 这种方法的缺点是它们不显示为文件。但正如MarkR's answer提醒你的那样,ls在巨大的目录上表现得非常糟糕。

    如果您坚持采用文件系统方法,许多使用大量文件的软件都会在aa/ ab/ ac/ ...... ay/ {{1}等子目录中组织这些文件。 }} az/ ... ba/ ...

答案 4 :(得分:0)

  
      
  • 将所有内容写入同一目录是否可以?或者我应该考虑为每个X文件创建一组子目录吗?
  •   

根据我的经验,如果您使用ls获取列表等内容,那么只会减慢包含许多文件的目录。但这主要是ls的错误,有更快的方法使用echo和find等工具列出目录的内容(见下文)。

  
      
  • 我是否需要将特定文件系统用于此类目录?
  •   

关于一个目录中的文件数量,我不这么认为。我确信某些文件系统在一个目录中的许多小文件中表现更好,而其他文件系统在大文件上做得更好。这也是个人品味的问题,类似于vi与emacs。我更喜欢使用XFS文件系统,这是我的建议。 : - )

  
      
  • 什么是更强大的替代方案?专业文件系统?哪个?
  •   

XFS绝对健壮且快速,我在许多地方使用它,如启动分区,oracle表空间,源代码控制空间,你可以命名它。它在删除性能方面缺乏一点,但除此之外它是一个安全的赌注。此外,它还支持在安装时增大尺寸(这实际上是一项要求)。那就是你只是删除分区,在相同的起始块和任何比原始分区更大的结束块重新创建它,然后在安装了文件系统的情况下运行xfs_growfs。

  
      
  • 任何其他考虑/推荐?
  •   

见上文。另外,在一个目录中有5000到10000个文件应该不成问题。在实践中,据我所知,除了“ls”和“rm”之类的实用程序之外,它并没有随意减慢文件系统的速度。但你可以这样做:

find * | xargs echo
find * | xargs rm

带有文件的目录树(例如以“a”等开头的文件名目录“a”)将带给您的好处是外观,它看起来更有条理。但是你的概述较少......所以你要做的事应该没问题。 : - )

我忽略了你可以考虑使用一种叫做“稀疏文件”http://en.wikipedia.org/wiki/Sparse_file

的东西

答案 5 :(得分:0)

在一个目录中拥有大量文件对性能不利。检查文件是否存在通常需要对目录进行O(n)扫描。创建新文件将需要锁定目录的同一扫描,以防止在创建新文件之前更改目录状态。有些文件系统可能更聪明(使用B树或其他),但实现对文件系统的优点和缺点的关联越少,对于长期维护就越好。假设有人可能决定有一天在网络文件系统(存储设备甚至云存储)上运行应用程序。使用网络存储时,巨大的目录是一个糟糕的主意。