
多数のキャッシュファイルが迅速に生成されるディレクトリがあります。このファイルは小さすぎるため、すべてのinodeを非常に迅速に消費します。
現在、私は12時間より古いすべてのファイルを見つけて削除するために次のコマンドを実行しています。
$ find ./cache -mtime +0.5 -exec rm {} \;
ただし、このコマンドはファイル生成よりも削除が遅くなります。大量のファイルをすばやく削除する他の方法を教えてくれる人はいますか?
答え1
find … -exec rm {} \;
rm
各ファイルに対してコマンドを実行します。新しいプロセスを開始するのは非常に高速ですが、単にファイルを削除するよりもはるかに遅いです。
find … -exec rm {} +
一括呼び出しされるので、はるかに高速です。バッチごとに一度実行するのにかかる費用をrm
支払い、バッチ削除を複数回実行します。rm
より速いのはrm
まったく電話しないことです。 Linuxのコマンドには、find
一致するファイルを削除する操作があります。-delete
find ./cache -type f -mtime +0.5 -delete
ただし、追いつかない速度でファイルを生成すると、find … -exec rm {} \;
設定に問題がある可能性があります。数百万のファイルが含まれている場合は、cache
より高速なアクセスのためにサブディレクトリに分割する必要があります。
答え2
以下を試してくださいxargs
。
find ./cache -mtime +0.5 -print0 | xargs -0 rm -f
@pradeepchhetriの説明が更新されました。
find
withを使用すると、-exec
見つかったファイルごとに1回find
呼び出されますrm
。したがって、10,000個のファイルをたくさん見つけたら、rm
10,000回呼び出したのです。
xargs
出力をfind
コマンド引数として扱うため、xargsは一度に処理できる数の引数をrm
提供します。つまり、これによりフォーク呼び出しが減り、プログラムがより速く実行されます。rm
rm -f file1 file2 ...
答え3
findが最善(最も簡単で慣用的な)方法ですが、
find $dir -exec rm {} +
そのディレクトリを横に移動し(プログラム用)、新しいディレクトリを作成して削除できます。
mv $idr old$dir && mkdir $dir && rm -rf old$dir
しかし、問題は生成されるファイルが多すぎる可能性があります。新しいファイルを作成するのではなく、既存のファイルに追加するようにプログラムを変更してみてはいかがでしょうか。その後、この(ログファイル)を横に移動すると、プログラムは新しいファイルを作成/追加できます。
fd = open("logfile","a+");
答え4
できるだけ早く多くのファイルを削除したい場合は問題ありませんが、システムls -f1 /path/to/folder/with/many/files/ | xargs rm
にIOの問題がある可能性があり、削除操作中にアプリケーションがクラッシュする可能性があるため、本番システムではこれを実行しないことをお勧めします。
このスクリプトは多くのファイルで動作し、システムのioloadには影響しません。
#!/bin/bash
# Path to folder with many files
FOLDER="/path/to/folder/with/many/files"
# Temporary file to store file names
FILE_FILENAMES="/tmp/filenames"
if [ -z "$FOLDER" ]; then
echo "Prevented you from deleting everything! Correct your FOLDER variable!"
exit 1
fi
while true; do
FILES=$(ls -f1 $FOLDER | wc -l)
if [ "$FILES" -gt 10000 ]; then
printf "[%s] %s files found. going on with removing\n" "$(date)" "$FILES"
# Create new list of files
ls -f1 $FOLDER | head -n 5002 | tail -n 5000 > "$FILE_FILENAMES"
if [ -s $FILE_FILENAMES ]; then
while read FILE; do
rm "$FOLDER/$FILE"
sleep 0.005
done < "$FILE_FILENAMES"
fi
else
printf "[%s] script has finished, almost all files have been deleted" "$(date)"
break
fi
sleep 5
done