多くのキャッシュされたファイルが非常に迅速に生成されるディレクトリがあります。これらは非常に小さなファイルであるため、すべてのiノードが非常に速く消費されます。
現在、私は次のコマンドを実行して、12時間以上経過したすべてのファイルを見つけて削除しています。
$ find ./cache -mtime +0.5 -exec rm {} \;
ただし、このコマンドが削除する速度は、ファイルが生成される速度よりも遅くなります。誰かが大量のファイルをすばやく削除する別の方法を教えてもらえますか?.
xargs
を使用してみてください:
find ./cache -mtime +0.5 -print0 | xargs -0 rm -f
@ pradeepchhetriの説明を更新
find
を-exec
とともに使用すると、find
が検出したすべてのファイルがrm
を1回呼び出します。したがって、大量のファイル、つまり10000ファイルを見つけた場合、rm
を10000回呼び出しました。
xargs
は、find
の出力をrm
へのコマンド引数として扱うため、xargsはrm
が一度に処理できる数の引数を提供します。つまり、rm -f file1 file2 ...
したがって、フォークの呼び出しが少なくなり、プログラムの実行が速くなります。
find … -exec rm {} \;
は、各ファイルに対してrm
コマンドを実行します。新しいプロセスの開始はかなり高速ですが、それでもファイルを削除するという単なる動作よりもはるかに低速です。
find … -exec rm {} +
はrm
をバッチで呼び出すため、はるかに高速です。バッチごとにrm
を実行するコストを支払うと、各バッチで多数の削除が実行されます。
さらに高速なのは、rm
をまったく呼び出さないことです。 Linuxのfind
コマンドにはアクション-delete
一致するファイルを削除します。
find ./cache -mtime +0.5 -delete
ただし、そのような速度でファイルを作成している場合、find … -exec rm {} \;
に対応できません。設定に問題がある可能性があります。 cache
に数百万のファイルが含まれている場合は、アクセスを高速化するために、ファイルをサブディレクトリに分割する必要があります。
作成率が削除率を超える場合は、キャッシュを完全に空にし、mtime評価なしで古いファイルを削除するのが最善です。
mv cache foobar
mkdir cache
# may require app restart
rm -rf foobar
Findは最良の(最も単純で慣用的な)アプローチですが、
find $dir -exec rm {} +
ディレクトリを脇に移動し、(プログラム用に)新しいディレクトリを作成してから、削除することができます...
mv $idr old$dir && mkdir $dir && rm -rf old$dir
しかし、おそらくあなたの問題は、あまりにも多くのファイルを作成することです。新しいファイルを作成するのではなく、既存のファイルに追加するようにプログラムを変更しませんか?次に、この(ログファイル)を脇に移動し、プログラムで新しいファイルを作成/追加できます。たとえば、
fd = open("logfile","a+");
できるだけ早く多くのファイルを削除したい場合は、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
別のLinux固有のソリューションは inotify(7) 機能を使用することです。ファイルが追加されたことを検出し、すぐに何かを実行して古いファイルを削除します。
OTOH、あなたはいくつかの XY問題 を持っていると思います。新しいファイルがたくさんあるのはなぜですか?おそらく、sqlite、またはGDBMインデックス付きファイル、またはいくつかの実際のデータベース(PostGresQL、MariaDB、MongoDBなど)を使用する方が良いかもしれません。おそらく、 git ?
rm -rf directory /は、1つのフォルダー内の数十億のファイルに対しても高速に動作します。やってみました。