我在我的 RHEL 服务器上生成了超过 50GB 的缓存文件(典型的文件大小为 200kb,因此没有文件很大)。当我尝试删除这些文件时,需要 8-10 个小时。
然而,更大的问题是系统负载在这 8 到 10 小时内达到临界值。无论如何,我可以在删除期间控制系统负载。
我尝试使用
nice -n19 rm -rf *
但这对系统负载没有帮助。
PS 我在superuser.com上问了同样的问题,但没有得到足够好的答案,所以在这里尝试。
我在我的 RHEL 服务器上生成了超过 50GB 的缓存文件(典型的文件大小为 200kb,因此没有文件很大)。当我尝试删除这些文件时,需要 8-10 个小时。
然而,更大的问题是系统负载在这 8 到 10 小时内达到临界值。无论如何,我可以在删除期间控制系统负载。
我尝试使用
nice -n19 rm -rf *
但这对系统负载没有帮助。
PS 我在superuser.com上问了同样的问题,但没有得到足够好的答案,所以在这里尝试。
以下是各种操作和文件系统的一些基准供您参考。(当然,在一个繁忙的系统上,您会得到不同的结果,但希望这会让您对预期的结果有所了解)。
如果我坐在你的椅子上,我会尝试获得该场景的基线基准:
一些数字。
在 5 年前的笔记本上, ext3安装了 rw,noatime,运行 top,仅此而已,使用 shell 脚本 create10kdirs.sh 创建 10k 目录
sudo time ./create10kdirs.sh
24.59user
20.70system
0:47.04elapsed
96%CPU (0avgtext+0avgdata 0maxresident)k80inputs+8outputs (1major+2735150minor)pagefaults 0swaps
使用 sudo time rm -rf
0.10user
19.75system
0:20.71elapsed
95%CPU (0avgtext+0avgdata 0maxresident)k0inputs+8outputs (0major+222minor)pagefaults 0swaps删除 10k 个目录
相同的硬件,ext4安装 rw,noatime 使用 shell 脚本创建 10k 目录 sudo time create10kdirs.sh
23.96user
22.31system
0:49.26elapsed
93%CPU (0avgtext+0avgdata0maxresident)k1896inputs+8outputs(20major+2715174minor)pagefaults 0swap
使用 sudo time rm -rf
0.13user
16.96system
0:28.21elapsed
60%CPU (0avgtext+0avgdata0maxresident)k10160inputs+0outputs(1major+219minor)pagefaults0swaps删除 10k 个目录
4 年旧笔记本,xfs安装 rw,relatime,USB 无障碍 sudo time create10kdirs.sh
14.19user
13.86system
0:29.75elapsed
94%CPU (0avgtext+0avgdata0maxresident)k432inputs+0outputs(1major+2735243minor)pagefaults 0swaps
使用sudo time rm -rf
0.13user
2.65system
0:08.20elapsed
33%CPU (0avgtext+0avgdata 0maxresident)k120inputs+0outputs (1major+222minor)pagefaults 0swaps删除 10k 个目录
结论:这个旧硬件将在大约 21 秒 * 40 = 12 分 40 秒内擦除 ext3 上的 400k 小文件+文件夹。在 xfs(没有障碍)上,它会在大约 5m20s 内完成。在这两个测试用例中,测试机器都没有承受重负载,但在我看来,您的问题似乎与您选择的文件系统并不严格相关。
EDIT2 另外,在运行高于基准测试后,我尝试使用 find 删除。-mindepth 1 -maxdepth 1 -删除
和结果!:
ext3 使用 sudo time find 删除 10k 个目录。-mindepth 1 -maxdepth 1 -delete
0.04user
0.44system
0:00.88elapsed
55%CPU (0avgtext+0avgdata 0maxresident)k516inputs+8outputs(1major+688minor)pagefaults0swaps
ext4 使用sudo time find删除 10k 个目录。-mindepth 1 -maxdepth 1 -delete
0.05user
0.66system
0:01.02elapsed
70%CPU (0avgtext+0avgdata 0maxresident)k568inputs+0outputs (1major+689minor)pagefaults交换
xfs 使用
sudo time find 删除 10k 目录。-mindepth 1 -maxdepth 1 -delete
0.06user
0.84system
0:04.55elapsed
19%CPU (0avgtext+0avgdata 0maxresident)k416inputs+0outputs (3major+685minor)pagefaults 0swaps
真正的结论是 rm -rf 不是很聪明,而且它对于大树的性能不佳。(前提是我的测试用例真的很有代表性)。
注意:我还测试了 xargs 变体,它很快,但没有上面的那么快。
正如您在评论中提到的,您正在使用
ext3
.众所周知,
rm
在 ext3 上处理大文件的性能很差;这是固定的东西之一ext4
。例如,请参阅这篇文章或kernelnewbies(其中提到范围提高了大文件的删除和截断速度)。我不知道这适用于您的典型文件大小。我希望它至少能应用一点,因为大约 200kB 你已经
ext3
在ext4
.作为一种解决方法(因为您可能不会
ext4
为此升级),每次只删除几个文件并sleep
在删除之间添加一个。它并不漂亮,但应该有助于减少负载。此外,如果在断电时丢失文件不是问题(因为它是某种缓存),您可以将它们放在一个单独的分区中,您可以
mkfs
在启动时再次使用该分区,并且在ext3
没有日志甚至ext2
. 高负载的原因可能是被刷新到磁盘的日志与读取冲突(您在另一篇文章中提到您有很多并发读取)。也许外壳是问题的原因。您应该直接使用 find :
find /dir -mindepth 1 -maxdepth 1 -delete
这可能相关,也可能不相关:但我曾遇到过
rm
无法处理我在命令行(通过星号运算符)提供的文件数量的情况。相反,我会使用 shell 中的以下命令:在这种情况下,您可能会删除树,在这种情况下,上述可能无法满足您的需要。您可能必须将删除操作分成几部分,例如
那只有 250,000 个左右的文件,应该不是问题——您使用的是什么文件系统,这个卷是否用于其他任何用途?
当您有很多像您描述的文件时,您每次都在调用该命令。此外,您还必须牢记日志 FS,您正在处理缓冲区命中和元数据,这会极大地影响处理时间。
最好的办法是使用上面提到的 find 命令,只使用不太明显的功能。
基本上“+”是你的朋友。这样做是在集合中创建文件名,并在每个集合中调用一次 rm 命令。这与 'xargs' 所做的几乎相同,但如果在 BSD/Linux 上,您不必担心正确的标志。
很好奇这对你来说能加速多少。因此,如果您还在,请回复。祝你好运 !
在研究了文件系统基准后,我选择了 JFS 作为 mymytv 视频文件的文件存储,因为文件删除速度很快(而且 mytv 等待删除完成,使 IO 变得迟缓)。
你也可以通过'find' 和'xargs' 来调用'rm' 而不是rm -rf。这可能会更快:
如何将这些文件的列表通过管道传输到 Perl 并使用它的 unlink 函数?
我同意它不应该花那么长时间,但根据所使用的底层存储,密集读取可能是预期的。我认为最终你最好的解决方案是添加额外的磁盘并在它们之间拆分你的活动。如果您沿着这条路线走,RAID 在某些情况下可能会有所帮助。iostat 在这些时间告诉您什么?您还可以使用 for 循环并将 'rm' 命令包装在 'time' 中以获取一些附加信息。
另一种可能性,当然取决于您的设置和应用程序,但也许您可以将这些缓存文件放在不同的分区上并定期格式化驱动器而不是删除文件?我认为运行 mkfs 会大大减少时间,但是当这种情况发生时您的应用程序将不可用,因此它并不理想。
我也喜欢更频繁地清理它们的想法。在 cron 中说,你每小时安排一次这样的事情:
find ./ -maxdepth 1 -type f -name "some pattern" -ctime +1 -exec rm -f {} \;
这将删除所有超过 24 小时的文件,而不是尝试一次全部完成。