サーバーに影響を与えずに何百万ものファイルを削除する方法


11

nginxキャッシュディレクトリを削除したいのですが、すぐに削除しました:

mv cache cache.bak
mkdir cache
service nginx restart

これで、cache.bak200万個のファイルがあるフォルダーができました。サーバーに影響を与えずに削除したいです。

単純なrm -rf cache.bakものはサーバーを破壊します。rmの実行中に最も単純なHTTP応答でも16秒かかるため、私はそれを行うことができません。

試しましたがionice -c3 rm -rf cache.bak、助けにはなりませんでした。サーバーにはSSDではなくHDDがありますが、おそらくSSDに問題はないかもしれません。

最良の解決策は、nginxの組み込みキャッシュマネージャーのように、何らかの調整を行うことだと思います。

これをどのように解決しますか?これを正確に実行できるツールはありますか?

Ubuntu 16.04上のext4


1
「rm -rf cache.bak」からどのように回復しましたか?名前変更を行ったときにnginxが実行されていたように見えるため、ファイル記述子を維持し、新しいディレクトリに切り替えた可能性もあります。nginxを完全にシャットダウンし、キャッシュを削除してから再起動する必要があると思います。
ヤンスタインマン

6
将来的には、キャッシュを別のファイルシステムに固定してください。そうすれば、そのファイルシステムを単純に破棄できます。これは、数百万のファイルを削除しようとするよりもはるかに高速です。数年前、これを無数のファイルを含むhylafaxスプールディレクトリで苦労して学びました。
デニスカースメーカー16

nicermを使用して実行しようとしましたか?
ヴラディスラフラストルスニー16

速い削除するには、rsyncのを試してみてください- -類似したケースへの回答unix.stackexchange.com/questions/37329/...
kawu

すべてのコメントをありがとう、私の調査結果をまとめて回答にまとめました。
ハイパーノット

回答:


9

次のような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内のすべてのファイルのリストを取得し、一度に5つのファイル名を削除スクリプトに渡します。

そのため、一度に削除するファイルの数と、各削除操作間の遅延時間を調整できます。


このソリューションのおかげで、私はそれを全体の記事に含めました。しかし、1つの質問、これは大きなnsをどのように処理していますか?通常、大きなディレクトリの*文字でエラーが発生する問題がありました。
ハイパーノット16

xargsコマンドラインの最大サイズを理解し、デフォルトでそれを超えないようにします。これには、一度に5パス以下の追加制限があります。
BowlOfRed 16

1
毎秒10ファイルの割合で、200万個のファイルを削除するのに55時間かかることに注意してください。
アンドリューヘンレ

4

誰かがコメントで述べたようにマウント/アンマウントできる別のファイルシステムにキャッシュを保存することを検討すべきです。それまでは、/usr/bin/find /path/to/files/ -type f -print0 -exec sleep 0.2 \; -exec echo \; -deletefindバイナリが/ usr / binの下にあり、画面で進行状況を確認したい場合に、この1つのライナーを使用できます。それに応じてスリープを調整し、HDDに過度のストレスがかからないようにします。


どこ-print0の出力もパイプしないので、ここでは必要ありませんfind
テロキルカネン16

rm-ingに興味があるかもしれません。パラノイアと呼びますが、正しいファイルを削除していることを常に確認したいと思います。
アレックス

ああ、私はコマンドを正しくデコードしていませんでした。
テロキルカネン16

3

findコマンドの出力を使用するスクリプトでioniceを試すことができます。次のようなもの:

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
)

ファイルシステムによっては、各ファイルを削除すると、そのディレクトリ全体が書き換えられる場合があります。大ヒットする可能性のある大きなディレクトリの場合。iノードテーブルに必要な追加の更新があり、場合によっては空き領域リストがあります。

ファイルシステムにジャーナルがある場合、変更はジャーナルに書き込まれます。適用された; ジャーナルから削除されました。これにより、書き込み集中型アクティビティのI / O要件が増加します。

キャッシュのジャーナルなしでファイルシステムを使用することもできます。

ioniceの代わりに、sleepコマンドを使用してアクションのレート制限を行うことができます。ioniceが機能しない場合でも機能しますが、すべてのファイルを削除するには時間がかかります。


2

私はここで多くの有用な回答/コメントを得ました。それを結論にしたいだけでなく、私の解決策も示したいと思います。

  1. はい、そのようなことを防ぐ最善の方法は、キャッシュディレクトリを別のファイルシステムに保持することです。ファイルシステムのNuking / Quick Formatには常に、せいぜい数秒(たぶん数分)しかかかりません。ファイルシステムの数とは無関係です。

  2. ionice/ nice削除処理は、実際にはほとんど何のI / Oを発生させないための解決策は、何もしませんでした。I / Oの原因は、ファイルが削除プロセスによって非常に速く削除されたときにカーネル/ファイルシステムレベルのキュー/バッファがいっぱいになると信じていたことです。

  3. 解決方法はTero Kilkanenのソリューションに似ていますが、シェルスクリプトを呼び出す必要はありませんでした。--bwlimit削除の速度を制限するために、rsyncの組み込みスイッチを使用しました。

完全なコマンド:

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

bwlimitは帯域幅をキロバイト単位で指定します。この場合、これはファイルのファイル名またはパスに適用されます。1 KBpsに設定すると、1時間あたり約100,000ファイル、つまり1秒あたり27ファイルが削除されました。ファイルにはのような相対パスがありcache.bak/e/c1/db98339573acc5c76bdac4a601f9ec1e、長さは47文字であるため、1秒あたり1000/47〜= 21ファイルになるため、1時間あたり100,000個のファイルの推測に似ています。

どうして--bwlimit=1?私はさまざまな値を試しました:

  • 10000、1000、100->システムは以前のように減速します
  • 10->しばらくの間、システムは非常に良好に動作しますが、1分に1回程度、部分的な速度低下を引き起こします。HTTP応答時間は1秒未満のままです。
  • 1->システムのスローダウンはまったくありません。私は急いではおらず、この方法で1日以内に200万個のファイルを削除できるので、それを選択します。

私はrsyncの組み込みメソッドのシンプルさが好きですが、このソリューションは相対パスの長さに依存します。ほとんどの人が試行錯誤によって正しい値を見つけるため、大きな問題ではありません。


あなたは、「MV-cache.dir歳を/ dev / null」のような何かをした場合は、ディスクの効果がどうなるか、今、私はとのように好奇心が強い
ivanivan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.