momo's Blog.

如何高效又节省资源的将上百万文件删除操作

字数统计: 458阅读时长: 1 min
2022/04/28 Share

前言

服务日志归档的脚本没有删源日志,导致服务器日志越来越多,磁盘满了。

随后上去简单粗暴的

1
find /logs/  -type f  -delete

然后loadavg直接满了, 服务告警。

如何正确删除大量的文件?

删除大量文件, 哪种方式更快。

1
2
3
time rm -rf *                   2m17.32s
time rm -rf directory 0m15.60s
time find directory -delete 0m16.97s

可以看到, rm -rf directory, 比 rm -rf * 快了9倍.

并且 find directory -deletefind directory -exec rm -f {} \; 更快.

并且如果服务器CPU性能足够强大, 使用 rsync -a --delete empty/ your_folder/ 会更快。

但是,上述的方式都是在不考虑服务器本身资源的情况下使用的。万一需要在业务运行状态下删除,那就要考虑以下如何限流了。

限流

为了防止服务器负载过高, 所以使用了以下命令

1
a=1;for log in $(find /tmp/battle_trace/ -ctime +5 -name "*.bin"); do [ $a -eq 500 ] && sleep 1 && a=0 ;rm -f $log; let a++; done

限流倒是限流了, 但是执行速度确实有点感人,删除几百万的文件,怕不是要好几天。。。

正确做法

搜索以后,发现了一个命令。

ionice
通过它执行的命令, 可以选择在什么情况下执行io操作。 我们删除文件选择-3, 当硬盘空闲模式下才执行删除。

脚本: nice_delete.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/bin/bash

MAX_LOAD=5
FILES=("$@")
BATCH=100

while [ ${#FILES[@]} -gt 0 ]; do
DEL=("${FILES[@]:0:$BATCH}")
ionice -c3 rm "${DEL[@]}"
echo -n "#"
FILES=("${FILES[@]:$BATCH}")
while [[ $(cat /proc/loadavg | awk '{print int($1)}') -gt $MAX_LOAD ]]; do
echo -n "."
sleep 1
done
done

上方脚本接收参数, 并且每次删除100个,删除后循环检查负载情况,如果大于设置的负载则sleep。

执行删除操作、

1
find  /tmp/battle_trace/ -type f  -name "*.bin" -exec /opt/nice_delete.sh {} \+

以上。。

CATALOG
  1. 1. 前言
  2. 2. 如何正确删除大量的文件?
    1. 2.1. 删除大量文件, 哪种方式更快。
    2. 2.2. 限流
  3. 3. 正确做法