在一个目录中保存多少文件有关系吗?如果是,一个目录中有多少文件是太多的,拥有太多文件的影响是什么?(这是在Linux服务器上。)

Background: I have a photo album website, and every image uploaded is renamed to an 8-hex-digit id (say, a58f375c.jpg). This is to avoid filename conflicts (if lots of "IMG0001.JPG" files are uploaded, for example). The original filename and any useful metadata is stored in a database. Right now, I have somewhere around 1500 files in the images directory. This makes listing the files in the directory (through FTP or SSH client) take a few seconds. But I can't see that it has any effect other than that. In particular, there doesn't seem to be any impact on how quickly an image file is served to the user.

我想过通过创建16个子目录来减少图像的数量:0-9和a-f。然后我将根据文件名的第一个十六进制数字将图像移动到子目录中。但是除了偶尔通过FTP/SSH列出目录之外,我不确定这样做是否有任何理由。


当前回答

≈13.5万份

NTFS | Windows 2012 server | 64bit | 4tb HDD | VBS

问题:当[单个]特定文件夹聚集了大约135,000个文件时,会出现灾难性的硬件问题。

“灾难性”= CPU过热,计算机关闭,更换硬件需要 "Specific Folder" =有一个VBS文件,用于将文件移动到子文件夹中 访问=该文件夹被多个客户端计算机自动访问/执行

基本上,我有一个位于文件服务器上的定制脚本。当自动化过程出现问题时(例如,文件溢出+大坝),那么特定的文件夹会被淹没[未移动的文件]。当客户端计算机继续执行脚本时,灾难就形成了。文件服务器最终读取了135,000多个文件;每天这样做几百次。这种工作过载最终导致我的CPU过热(92°C等);结果导致我的机器崩溃。

解决方案:确保您的文件组织脚本永远不必处理包含135,000多个文件的文件夹。

其他回答

“取决于文件系统” 一些用户提到性能影响取决于所使用的文件系统。当然可以。像EXT3这样的文件系统可能非常慢。但是即使您使用EXT4或XFS,也不能防止通过ls或查找或通过FTP等外部连接列出文件夹会变得越来越慢。

解决方案 我喜欢和@armandino一样的方式。为此,我使用PHP中的这个小函数将id转换为每个目录1000个文件的文件路径:

function dynamic_path($int) {
    // 1000 = 1000 files per dir
    // 10000 = 10000 files per dir
    // 2 = 100 dirs per dir
    // 3 = 1000 dirs per dir
    return implode('/', str_split(intval($int / 1000), 2)) . '/';
}

或者你可以使用第二个版本,如果你想使用字母数字字符:

function dynamic_path2($str) {
    // 26 alpha + 10 num + 3 special chars (._-) = 39 combinations
    // -1 = 39^2 = 1521 files per dir
    // -2 = 39^3 = 59319 files per dir (if every combination exists)
    $left = substr($str, 0, -1);
    return implode('/', str_split($left ? $left : $str[0], 2)) . '/';
}

结果:

<?php
$files = explode(',', '1.jpg,12.jpg,123.jpg,999.jpg,1000.jpg,1234.jpg,1999.jpg,2000.jpg,12345.jpg,123456.jpg,1234567.jpg,12345678.jpg,123456789.jpg');
foreach ($files as $file) {
    echo dynamic_path(basename($file, '.jpg')) . $file . PHP_EOL;
}
?>

1/1.jpg
1/12.jpg
1/123.jpg
1/999.jpg
1/1000.jpg
2/1234.jpg
2/1999.jpg
2/2000.jpg
13/12345.jpg
12/4/123456.jpg
12/35/1234567.jpg
12/34/6/12345678.jpg
12/34/57/123456789.jpg

<?php
$files = array_merge($files, explode(',', 'a.jpg,b.jpg,ab.jpg,abc.jpg,ddd.jpg,af_ff.jpg,abcd.jpg,akkk.jpg,bf.ff.jpg,abc-de.jpg,abcdef.jpg,abcdefg.jpg,abcdefgh.jpg,abcdefghi.jpg'));
foreach ($files as $file) {
    echo dynamic_path2(basename($file, '.jpg')) . $file . PHP_EOL;
}
?>

1/1.jpg
1/12.jpg
12/123.jpg
99/999.jpg
10/0/1000.jpg
12/3/1234.jpg
19/9/1999.jpg
20/0/2000.jpg
12/34/12345.jpg
12/34/5/123456.jpg
12/34/56/1234567.jpg
12/34/56/7/12345678.jpg
12/34/56/78/123456789.jpg
a/a.jpg
b/b.jpg
a/ab.jpg
ab/abc.jpg
dd/ddd.jpg
af/_f/af_ff.jpg
ab/c/abcd.jpg
ak/k/akkk.jpg
bf/.f/bf.ff.jpg
ab/c-/d/abc-de.jpg
ab/cd/e/abcdef.jpg
ab/cd/ef/abcdefg.jpg
ab/cd/ef/g/abcdefgh.jpg
ab/cd/ef/gh/abcdefghi.jpg

正如你所看到的$int-version每个文件夹最多包含1000个文件和99个目录,其中包含1000个文件和99个目录…

但是不要忘记,许多目录会导致相同的性能问题!

最后,您应该考虑如何减少文件总数。根据你的目标,你可以使用CSS精灵组合多个小图像,如头像,图标,微笑等,或者如果你使用许多小的非媒体文件,考虑将它们组合在JSON格式。以我为例,我有数千个迷你缓存,最后我决定将它们组合成10个。

我遇到的最大问题是在32位系统上。一旦你通过了一个特定的数字,像'ls'这样的工具就会停止工作。

一旦您通过了这个障碍,试图对该目录做任何事情都将成为一个巨大的问题。

我也有同样的问题。试图在ext4的Ubuntu服务器中存储数百万个文件。结束运行我自己的基准测试。发现平面目录执行得更好,同时使用起来更简单:

写了一篇文章。

我尊重这并不能完全回答你的问题,多少是太多了,但解决长期问题的一个想法是,除了存储原始文件元数据外,还存储它存储在磁盘上的哪个文件夹-规范化元数据。一旦一个文件夹的增长超出了性能、美观或其他原因的限制,你只需创建第二个文件夹并开始在那里放置文件……

我现在正在研究一个类似的问题。我们有一个层次结构的目录结构,并使用映像id作为文件名。例如,其中放置了id=1234567的图像

..../45/67/1234567_<...>.jpg

使用最后4位数字来确定文件的位置。

对于几千张图像,您可以使用一级层次结构。出于效率/备份/其他考虑,系统管理员建议在任何给定目录(ext3)中不超过几千个文件。