在Linux中,如果单个目录下有太多文件,会发生什么?

mwecs4sa  于 2022-11-22  发布在  Linux
关注(0)|答案(7)|浏览(569)

如果在一个目录中有1,000,000个单独的文件(大部分是100k大小),平面(没有其他目录和文件在其中),是否会有任何效率的妥协或任何其他可能的方式的缺点?

w1e3prcc

w1e3prcc1#

ARG_MAX会对此提出异议...例如,rm -rf *(在目录中时)会说“参数太多”。想要做某种globbing(或shell)的实用程序会有一些功能中断。
如果该目录对公众可用(比如通过ftp或web服务器),则可能会遇到其他问题。
对任何给定文件系统的影响完全取决于该文件系统。这些文件的访问频率是多少,文件系统是什么?记住,Linux(默认情况下)倾向于将最近访问的文件保存在内存中,而将进程置于交换中,这取决于您的设置。该目录是否通过http提供服务?Google是否会看到并爬取它?如果是,您可能需要调整VFS缓存压力和交换性。

编辑:

ARG_MAX是一个系统范围的限制,限制程序入口点可以提供多少参数。因此,让我们以'rm'为例,“rm -rf ”-shell将''转换为一个空格分隔的文件列表,而这些文件列表又成为'rm'的参数。
同样的事情也会发生在ls和其他几个工具上。例如,如果太多的文件以'foo'开头,ls foo* 可能会崩溃。
我建议(不管使用的是什么文件系统)将其分解为更小的目录块,仅仅是因为这个原因。

mgdq6dx1

mgdq6dx12#

我在ext 3和dir_index上使用大目录的经验:

  • 如果您知道要访问的文件的名称,则几乎没有任何损失
  • 如果您要执行需要读入整个目录条目的操作(例如在该目录上执行一个简单的ls),则第一次需要花费几分钟时间。
  • 如果文件数量太多,就会遇到ARG_MAX等问题。这基本上意味着通配符(*)不再总是像预期的那样工作。只有当您确实想一次对所有文件执行操作时,才会出现这种情况

然而,如果没有dir_index,你就真的完蛋了:-D

jhkqcmku

jhkqcmku3#

大多数发行版默认使用Ext3,它可以对大目录使用b树索引。一些发行版默认启用了dir_index功能,而另一些发行版则需要你自己启用。如果你启用了它,即使对数百万个文件也不会有任何减慢。
要查看dir_index功能是否已激活,请执行以下操作(以root用户身份):

tune2fs -l /dev/sdaX | grep features

要激活dir_index功能(以root用户身份),请执行以下操作:

tune2fs -O dir_index /dev/sdaX
e2fsck  -D /dev/sdaX

/dev/sdaX替换为要为其激活的分区。

6vl6ewon

6vl6ewon4#

当你不小心在那个目录中执行了“ls”,或者使用了制表符完成,或者想要执行“rm *",你就会遇到大麻烦。另外,根据你的文件系统,可能会有性能问题。
它被认为是一个好的做法,将您的文件分组到目录中命名的前2或3个字符的文件名,例如。

aaa/
   aaavnj78t93ufjw4390
   aaavoj78trewrwrwrwenjk983
   aaaz84390842092njk423
   ...
abc/
   abckhr89032423
   abcnjjkth29085242nw
   ...
...
hsgswve4

hsgswve45#

显而易见的答案是,在没有任何技术限制的情况下,该文件夹对人类来说将非常难以使用,(读取ls的输出所需的时间是一个原因,还有许多其他原因)有没有一个很好的理由为什么不能拆分成子文件夹?

a11xaf1n

a11xaf1n6#

不是每个文件系统都支持这么多文件。
在其中一些(ext2、ext3、ext4)上,很容易达到inode限制。

u7up0aaq

u7up0aaq7#

我有一台主机,它的目录中有10M个文件。(不要问)文件系统是ext4。

ls

我发现的一个限制是,我的shell脚本读取文件(因为AWS snapshot restore is a lie和文件在第一次读取之前是不存在的)不能处理参数列表,所以我需要做两遍。

find /path/to_dir/ -wholename '*.ldb'| tee filenames.txt

然后从包含文件名的文件中读取,并读取所有文件。(具有有限的并行性)

while read -r line; do
if test "$(jobs | wc -l)" -ge 10; then
wait -n
fi
{
   #do something with 10x fanout
} &
done < filenames.txt

如果有人发现在处理太多文件时,特定的解决方法很有用,请在此处发布。

相关问题