这可能是一个非常普遍的问题,但我真的很想找到一些详细的答案或线索。
我正在和一个朋友讨论这个问题,试图说服他将 300,000 多个文件从一个文件夹放入多个文件夹中(例如每个子目录 1000 个)。这些文件是图像,用于在线网页浏览,例如:
www.example.com/folder/1.png
.
.
.
www.example.com/folder/300000.png
我只记得很多年前我在 Youtube 这样的在线视频服务公司工作时,我们把截图放在一个文件夹中,然后服务器经常崩溃。当时有一个“谣言”说人们不应该把很多文件放在一个文件夹中,但我们不知道具体原因。
那么我应该在一个文件夹中放多少个文件?如果有限制,为什么?有什么推荐的设计方法吗?
我的服务器信息:
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 7.8 (wheezy)
Release: 7.8
Codename: wheezy
核心构建版本:
Linux linode 4.1.5-x86_64-linode61 #7 SMP Mon Aug 24 13:46:31 EDT 2015 x86_64 GNU/Linux
我猜想这种情况适用于许多不同类型的服务器软件。
答案1
这其实不是什么大问题更新文件系统,例如 XFS 和 ext4,但在较旧的或配置错误的文件系统上,这可能是一个严重的问题。
对于较旧的 Linux 文件系统(例如 ext3),目录只是无序文件列表。
无序性很重要,因为这意味着系统在目录中查找文件的唯一方法是从头到尾搜索。
如果目录包含 3,000 个文件,则需要平均的1,500 次比较才能找到目录中的随机文件。但如果目录中包含 300,000 个文件,则需要平均的进行 150,000 次比较才能在该目录中找到一个随机文件。
无论是哪种情况,如果目录条目尚未缓存在 RAM 中,则必须从磁盘加载,这将使文件访问时间显著增加,与目录的大小成比例。显然,小目录项的加载速度比大目录项快。
因此,很多当您使用更分层的目录结构将大量文件分成不同的目录时,速度会更快。
XFS 不会受到此问题的影响,因为它使用哈希表查找目录条目。因此,它可以像处理只有一个文件的目录一样轻松地处理包含数十万个文件的目录。但它仍然需要从磁盘加载更大的数据结构。不过,如果系统中有足够的 RAM,这实际上不是一个实际问题。
Ext4 也使用散列目录索引。
答案2
当单个目录包含许多(数万、数十万或数百万)文件或子目录时,许多文件系统会变慢,甚至可能存在硬性上限,但是否会变慢以及变慢的程度取决于您选择的文件系统和 IO 操作。查看 Wikipedia文件系统特性比较。
显然列出并排序目录许多文件的成本会更高,但即使通过名称检索文件,对于较大的目录,成本也会变得更加昂贵。
一个常见的解决方案是根据文件名或从文件名派生而来创建多级子目录结构。
答案3
这有多重要取决于您使用的文件系统,有时还取决于存储实现方式的其他方面。它也可能取决于使用模式。
一些较旧的文件系统在文件数量超过 1000 个左右时性能会大幅下降。较新的文件系统的情况较少,但也不是完全没有问题。
由于文件数量众多,目录节点会变得很大。每次更改时都需要重写。这可能会带来性能问题。
如果您的存储是联网的,那么与写入目录相关的锁定可能会成为一个问题。例如,如果您有一组 Web 服务器共享一个大型目录来存储会话文件,而这些文件在每次 Web 访问时都会发生变化,那么该目录的性能可能会非常糟糕,本质上是序列化访问,因为进程等待锁定目录节点。将会话文件散列到较小的目录中意味着大多数会话文件访问不会对需要锁定的给定会话写入产生影响。