在 Linux 上删除大量文件会消耗大量 CPU

在 Linux 上删除大量文件会消耗大量 CPU

我在 RHEL 服务器上生成了超过 50GB 的缓存文件(典型文件大小为 200kb,因此文件并不大)。当我尝试删除这些文件时,需要 8-10 小时。

然而,更大的问题是,在这 8-10 小时内,系统负载变得非常高。在删除期间,我有什么办法可以控制系统负载吗?

我尝试使用

nice -n19 rm -rf *

但这对系统负载没有帮助。

PS 我问了同样的问题超级用户网但没有得到足够好的答案,所以在这里尝试。

答案1

这里有一些基准供您参考。(在繁忙的系统上,您当然会得到不同的结果,但希望这能让您了解会发生什么)。

如果我站在你的立场上,我会尝试获取该场景的基线基准:

  • 确定在与其他一切隔离的裸机上操作需要多长时间(是的,即使在相当旧的硬件上,它也应该花费远远少于 7-8 小时的时间)。
  • 尝试添加通常以受控方式发生的其他操作,并查看实际是什么导致其运行时间如此之长

一些数字。

在五年前的笔记本上, 扩展挂载 rw、noatime、运行 top 等,使用 shell 脚本 create10kdirs.sh 创建 10k 个目录

#!/bin/bash
for i in $(seq 10000)
do
    mkdir $i
done

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 0swaps


使用 sudo time rm -rf 0.13user
16.96system
0:28.21elapsed
60%CPU (0avgtext+0avgdata0maxresident)k10160inputs+0outputs(1major+219minor)pagefaults0swaps删除 10k 个目录

4年前的笔记本,軟體系在 USB 上安装 rw、relatime、nobarrier 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删除 10k 个目录
0:08.20已过去
33%CPU(0avgtext+0avgdata 0maxresident)k120输入+0输出(1major+222minor)页面错误0交换

结论:这款旧硬件将在大约 21 秒 * 40 = 12 分 40 秒内删除 ext3 上的 400k 个小文件+文件夹。在 xfs(无屏障)上,它将在大约 5 分 20 秒内完成。当然,在两种测试情况下,测试机器都没有承受重负载,但在我看来,您的问题似乎与您选择的文件系统没有严格关系。

EDIT2 此外,在运行上述基准测试后,我尝试使用 find 进行删除。-mindepth 1 -maxdepth 1 -delete

和结果!:

ext3 使用 sudo time find 删除 10k 个目录。-mindepth 1 -maxdepth 1 -delete
0.04user
0.44system
0:00.88已过
55%CPU (0avgtext+0avgdata 0maxresident)k516输入+8输出(1major+688minor)页面错误0交换

ext4 使用 sudo time find 删除 10k 个目录
。-mindepth 1 -maxdepth 1 -delete
0.05user
0.66system
0:01.02已过去
70%CPU (0avgtext+0avgdata 0maxresident)k568inputs+0outputs (1major+689minor)页面错误交换

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 变体,它很快,但不如上面的快。

答案2

正如您在评论中提到的,您正在使用ext3

众所周知,rmext3 上大文件的性能较差;这是在 中修复的问题之一ext4。例如,参见这个帖子, 或者内核新手(其中提到范围可以提高大文件的删除和截断速度)。

我不知道这对您的典型文件大小有多大影响。我预计它至少会有点影响,因为对于大约 200kB 的文件,您可能已经在 上使用间接块ext3,而 可能只使用 上的一个区段ext4


作为一种解决方法(因为你可能不会为此而升级ext4),每次只删除几个文件,并sleep在删除之间添加一个。虽然不太美观,但应该有助于减少负载。

此外,如果断电时文件丢失不是问题(因为它是某种缓存),您可以将它们放在单独的分区中,mkfs并在启动时再次使用,而ext3无需日志甚至ext2。高负载的原因可能是日志被刷新到磁盘与读取冲突(您在另一篇文章中提到您有很多并发读取)。

答案3

也许 shell 是导致问题的原因。您应该直接使用 find :find /dir -mindepth 1 -maxdepth 1 -delete

答案4

这只有 250,000 个文件左右,实际上不应该是个问题 - 您使用什么文件系统,该卷是否用于其他用途?

相关内容