如何在不干扰服务器的情况下删除数百万个文件

我想删除一个nginxcaching目录,我很快就清除了这个目录:

mv cache cache.bak mkdir cache service nginx restart 

现在我有一个有200万个文件的cache.bak文件夹。 我想删除它,而不会打扰服务器。

一个简单的rm -rf cache.bak服务器,即使最简单的HTTP响应在rm运行时也需要16秒,所以我不能这么做。

我试过ionice -c3 rm -rf cache.bak ,但是没有帮助。 服务器有一个硬盘,而不是一个SSD,可能在SSD上,这可能不成问题。

我相信最好的解决scheme会是某种限制,比如nginx的内置cachingpipe理器。

你将如何解决这个问题? 有什么工具可以做到这一点?

在Ubuntu 16.04上的ext4

像这样做一个bash脚本:

 #!/bin/bash rm -- "$*" sleep 0.5 

例如,以名称deleter.sh保存。 运行chmod u+x deleter.sh使其可执行。

该脚本删除所有传递给它的文件作为参数,然后睡眠0.5秒。

然后,你可以运行

 find cache.bak -print0 | xargs -0 -n 5 deleter.sh 

此命令检索cache.bak中的所有文件的列表,并一次将五个文件名传递给删除脚本。

因此,您可以调整一次删除多less个文件,以及每个删除操作之间的延迟时间。

您应该考虑将caching保存在单独的文件系统上,您可以像注释中指出的那样挂载/卸载。 直到你这样做,你可以使用这一行/usr/bin/find /path/to/files/ -type f -print0 -exec sleep 0.2 \; -exec echo \; -delete /usr/bin/find /path/to/files/ -type f -print0 -exec sleep 0.2 \; -exec echo \; -delete /usr/bin/find /path/to/files/ -type f -print0 -exec sleep 0.2 \; -exec echo \; -delete假设您的查找二进制文件位于/ usr / bin下,并希望在屏幕上查看进度。 相应地调整睡眠,所以你不要过度压力你的硬盘。

您可能想要尝试使用find命令输出的脚本。 像下面这样:

 ionice -c3 $( for file in find cache.bak -type f; do rm $file done for dir in find cache.bak -depthe -type d -empty; do rmdir $dir done ) 

根据文件系统的不同,每个文件删除都可能导致重写整个目录。 对于大型目录,可以相当受欢迎。 inode表还需要额外的更新,可能还有一个空闲空间列表。

如果文件系统有日志,则将更改写入日志; 应用; 并从期刊中删除。 这增加了写入密集型活动的I / O要求。

您可能希望使用没有日志的文件系统作为caching。

您可以使用睡眠命令来限制操作,而不是使用ionice。 这将工作,即使ionice没有,但它将需要很长的时间来删除所有的文件。

我在这里得到了很多有用的答案/评论,我想总结以及展示我的解决scheme。

  1. 是的, 防止发生这种事情的最好方法是将caching目录保存在单独的文件系统上。 快速格式化文件系统最多只需要几秒钟(可能是几分钟),与文件/目录的数量无关。

  2. ionice / nice解决scheme没有做任何事情,因为删除过程实际上几乎没有造成I / O。 造成I / O的原因是当删除过程删除文件太快时,我认为内核/文件系统级别的队列/缓冲区已满。

  3. 我解决这个问题的方式类似于Tero Kilkanen的解决scheme,但是不需要调用shell脚本。 我使用rsync内置的--bwlimit开关来限制删除的速度。

完整的命令是:

 mkdir empty_dir rsync -v -a --delete --bwlimit=1 empty_dir/ cache.bak/ 

现在,bwlimit指定千字节的带宽,在这种情况下应用于文件的文件名或path。 通过设置为1 KBps,它每小时删除大约100,000个文件,或每秒27个文件。 文件有相对path,如cache.bak/e/c1/db98339573acc5c76bdac4a601f9ec1e ,长度为47个字符,所以每秒钟会给出1000/47〜= 21个文件,类似于我每小时100,000个文件的猜测。

现在为什么--bwlimit=1 ? 我尝试了各种值:

  • 10000,1000,100 – >系统像以前一样减速
  • 10 – >系统工作一段时间,但一分钟左右产生部分减速。 HTTP响应时间仍然<1秒。
  • 1 – >没有系统减速。 我不急,200万个文件可以在<1天这样删除,所以我select它。

我喜欢rsync内置方法的简单性,但是这个解决scheme取决于相对path的长度。 不是一个大问题,因为大多数人会通过反复试验find正确的价值。