Kip*_*Kip 544 filesystems limit
我保存在一个目录中的文件数量是否重要?如果是这样,目录中有多少文件太多,文件太多会有什么影响?(这是在Linux服务器上.)
背景:我有一个相册网站,上传的每个图像都重命名为8位十六进制数字(例如a58f375c.jpg).这是为了避免文件名冲突(例如,如果上传了大量"IMG0001.JPG"文件).原始文件名和任何有用的元数据都存储在数据库中.现在,我在images目录中有大约1500个文件.这使得列出目录中的文件(通过FTP或SSH客户端)需要几秒钟.但我看不出它除此之外还有什么影响.特别是,对于向用户提供图像文件的速度似乎没有任何影响.
我想过通过制作16个子目录来减少图像数量:0-9和af.然后我会根据文件名的第一个十六进制数字将图像移动到子目录中.但我不确定是否有任何理由这样做,除了偶尔通过FTP/SSH列出目录.
ISW*_*ISW 708
小智 182
我在一个ext3目录中有超过800万个文件.libc中readdir()
这是由使用的find
,ls
而且大部分在此线程讨论的其他方法,列出大的目录.
在这种情况下原因ls
和find
速度很慢的是,一次readdir()
只能读取32K的目录条目,因此在慢速磁盘上,需要许多次读取才能列出目录.这个速度问题有一个解决方案.我在以下网址写了一篇非常详细的文章:http://www.olark.com/spw/2011/08/you-can-list-a-directory-with-8-million-files-but-not-with- LS /
关键点是:getdents()
直接使用- http://www.kernel.org/doc/man-pages/online/pages/man2/getdents.2.html而不是基于libc的任何内容,readdir()
因此您可以指定缓冲区从磁盘读取目录条目时的大小.
S..*_*S.. 60
我有一个包含88,914个文件的目录.像你自己一样,它用于存储缩略图和Linux服务器.
通过FTP或php函数列出的文件很慢,但是在显示文件时也会出现性能损失.例如www.website.com/thumbdir/gh3hg4h2b4h234b3h2.jpg的等待时间为200-400毫秒.作为另一个站点的比较,我在一个目录中有大约100个文件,在等待约40ms之后显示图像.
我已经给出了这个答案,因为大多数人刚刚写了目录搜索功能将如何执行,你不会在拇指文件夹上使用 - 只是静态显示文件,但是会对如何实际使用文件的性能感兴趣.
Bar*_*ler 56
它取决于Linux服务器上使用的特定文件系统.现在默认是使用dir_index的ext3,这使得搜索大型目录的速度非常快.
所以速度不应该是一个问题,除了你已经注意到的那个,这是列表需要更长的时间.
一个目录中的文件总数有限制.我似乎记得它肯定能够处理32000个文件.
Ste*_*Kuo 47
请记住,在Linux上,如果您的目录文件太多,则shell可能无法扩展通配符.我在Linux上托管的相册中存在此问题.它将所有已调整大小的图像存储在单个目录中.虽然文件系统可以处理许多文件,但shell不能.例:
-shell-3.00$ ls A*
-shell: /bin/ls: Argument list too long
Run Code Online (Sandbox Code Playgroud)
要么
-shell-3.00$ chmod 644 *jpg
-shell: /bin/chmod: Argument list too long
Run Code Online (Sandbox Code Playgroud)
arm*_*ino 23
我现在正在研究类似的问题.我们有一个层次结构的目录结构,并使用图像ID作为文件名.例如,id=1234567
放入的图像
..../45/67/1234567_<...>.jpg
Run Code Online (Sandbox Code Playgroud)
使用最后4位数来确定文件的去向.
使用几千个图像,您可以使用一级层次结构.我们的系统管理员建议在任何给定目录(ext3)中只有几千个文件用于效率/备份/他想到的任何其他原因.
T.J*_*der 17
为了它的价值,我只是在ext4
文件系统上创建了一个目录,其中包含1,000,000个文件,然后通过Web服务器随机访问这些文件.我没有注意到访问那些(例如)那里只有10个文件的溢价.
这与我几年前这样做的经历截然不同ntfs
.
如果实现目录分区方案所涉及的时间很少,我赞成它.第一次必须调试涉及通过控制台操作10000文件目录的问题时,您将理解.
例如,F-Spot将照片文件存储为YYYY\MM\DD\filename.ext,这意味着我必须处理的最大目录,而手动操作我的~20000照片集大约是800个文件.这也使得文件更容易从第三方应用程序中浏览.永远不要假设您的软件是唯一可以访问您的软件文件的东西.
它绝对取决于文件系统.许多现代文件系统使用不错的数据结构来存储目录的内容,但是较旧的文件系统通常只是将条目添加到列表中,因此检索文件是O(n)操作.
即使文件系统做得正确,列出目录内容的程序仍然绝对可能搞乱并进行O(n ^ 2)排序,所以为了安全起见,我总是限制每个文件的数量目录不超过500.
问题归结为您将如何处理这些文件。
在 Windows 下,任何超过 2k 文件的目录在资源管理器中对我来说打开速度都很慢。如果它们都是图像文件,则超过 1k 的文件往往在缩略图视图中打开速度非常慢。
有一次,系统施加的限制是 32,767。现在它更高了,但即使是这样,在大多数情况下一次处理的文件也太多了。
ext3实际上确实具有目录大小限制,并且它们取决于文件系统的块大小。没有每个目录的“最大数量”的文件,而是每个目录的“用于存储文件条目的最大块的数量”。具体来说,目录本身的大小不能超过高度为3的b树,并且树的扇出取决于块大小。有关更多详细信息,请参见此链接。
https://www.mail-archive.com/cwelug@googlegroups.com/msg01944.html
最近,我在一个以2K块格式化的文件系统上被这个问题所困扰,warning: ext3_dx_add_entry: Directory index full!
当我从另一个ext3文件系统复制时,该文件系统莫名其妙地得到了目录已满的内核消息。就我而言,只有480,000个文件的目录无法复制到目标位置。
“取决于文件系统”
一些用户提到性能影响取决于使用的文件系统。当然。像 EXT3 这样的文件系统可能会很慢。但是,即使你使用EXT4或者XFS你不能阻止通过上市文件夹ls
或find
或通过像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)) . '/';
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您想使用字母数字字符,则可以使用第二个版本:
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)) . '/';
}
Run Code Online (Sandbox Code Playgroud)
结果:
<?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
Run Code Online (Sandbox Code Playgroud)
正如您所看到的$int
-version 每个文件夹包含多达 1000 个文件和多达 99 个目录,其中包含 1000 个文件和 99 个目录......
但不要忘记,许多目录会导致相同的性能问题!
最后,您应该考虑如何减少文件总数。根据您的目标,您可以使用 CSS 精灵组合多个小图像,如头像、图标、笑脸等,或者如果您使用许多小型非媒体文件,请考虑组合它们,例如以 JSON 格式。就我而言,我有数千个迷你缓存,最后我决定将它们组合成 10 个。
小智 5
上面的大多数答案都没有表明原始问题没有“一刀切”的答案。
在今天的环境中,我们拥有大量不同硬件和软件的组合——有些是 32 位的,有些是 64 位的,有些是尖端的,有些是经过验证的——可靠且永不改变。除此之外还有各种新旧硬件、新旧操作系统、不同的供应商(Windows、Unixes、Apple 等)以及无数的实用程序和服务器。随着硬件的改进和软件转换为 64 位兼容性,让这个非常庞大而复杂的世界的所有部分在快速变化的步伐中很好地发挥作用必然会有相当大的延迟。
恕我直言,没有一种方法可以解决问题。解决方案是研究各种可能性,然后通过反复试验找到最适合您特定需求的方法。每个用户必须确定什么对他们的系统有效,而不是使用千篇一律的方法。
例如,我有一个包含一些非常大的文件的媒体服务器。结果是只有大约 400 个文件填充 3 TB 驱动器。仅使用了 1% 的 inode,但使用了总空间的 95%。其他人,有很多较小的文件,可能会在它们接近填充空间之前用完 inode。(根据经验,在 ext4 文件系统上,每个文件/目录使用 1 个 inode。)虽然理论上一个目录中可能包含的文件总数几乎是无限的,但实用性决定了整体使用情况决定了实际单位,而不是只是文件系统功能。
我希望以上所有不同的答案都促进了思考和解决问题的能力,而不是给进步带来不可逾越的障碍。
我一直遇到同样的问题。试图在ext4的Ubuntu服务器中存储数百万个文件。结束了运行自己的基准测试。发现平面目录在使用更简单的同时性能更好:
写了一篇文章。
归档时间: |
|
查看次数: |
297850 次 |
最近记录: |