数百万のgif画像でいっぱいになったディレクトリがありました。rmコマンドには多すぎます。
私はこのような検索コマンドを試しています:
find . -name "*.gif" -print0 | xargs -0 rm
問題は、マシンが本当に悪い状態に陥り、サーバーであるために顧客にタイムアウトが発生することです。
マシンをロックせずに、これらのファイルをすべて削除するより速い方法はありますか?
rm -rf
より速いだろうそれの試してみる価値。。
数百万のgif画像でいっぱいになったディレクトリがありました。rmコマンドには多すぎます。
私はこのような検索コマンドを試しています:
find . -name "*.gif" -print0 | xargs -0 rm
問題は、マシンが本当に悪い状態に陥り、サーバーであるために顧客にタイムアウトが発生することです。
マシンをロックせずに、これらのファイルをすべて削除するより速い方法はありますか?
rm -rf
より速いだろうそれの試してみる価値。。
回答:
速くすることは必ずしもあなたが望むものではありません。実際に実行速度を遅くしたい場合があるので、実行中に削除するリソースが少なくなります。
nice(1)を使用して、コマンドの優先順位を下げます。
nice find . -name "*.gif" -delete
I / Oバウンドプロセスの場合、nice(1)では不十分な場合があります。Linuxスケジューラーは、CPUだけでなくI / Oも考慮しますが、I / Oの優先順位をより細かく制御したい場合があります。
ionice -c 2 -n 7 find . -name "*.gif" -delete
それでうまくいかない場合は、スリープを追加して本当に遅くすることもできます。
find . -name "*.gif" -exec sleep 0.01 \; -delete
sleep
追加-を使用してionice -c 3
いるにもかかわらず、サーバーがIOで窒息する問題がありました。(もちろん)ファイルをクリアするのにかかる時間は大幅に増加しますが、アプリケーションを停止するよりも待ちたいのですが…
Linuxを実行しており、このタスクはおそらくI / Oにバインドされているため、次のコマンドを使用して、コマンドにアイドルI / Oスケジューラの優先順位を付けることをお勧めしますionice(1)
。
ionice -c3 find . -name '*.gif' -delete
元のコマンドと比較すると、のパイプを使用しないことで、CPUサイクルをさらに節約できxargs
ます。
ionice -c3
IOがアイドル状態のときにprioを下げて実行するようにします。以来ことに注意してください-delete
検索するための標準ではありません、あなたは、このコマンドを使用して(それが動作することフィードバックを含む)と同じ操作を行うことができますionice -c 3 find . -name '*.gif' -exec echo {} \; -exec rm {} \;
-ゆっくりではあるが重要なプロセスの無iowaits。
簡単な方法はありません。ディスクのソフトフォーマットからのアパートです。ファイルは一度にrm に渡されます(コマンドラインの制限まで、に設定することもできますxargs
)。これは、各ファイルでrmを呼び出すよりもはるかに優れています。だから、間違いなく、より速い方法はありません。
使用するnice
(またはrenice
実行中のプロセスで)のは、ディスクではなくCPUリソースをスケジュールするためです。また、CPU使用率は非常に低くなります。これはLinuxの弱点です。1つのプロセスがディスクを「使い果たす」(つまり、多くのディスクで動作する)と、マシン全体が動かなくなります。リアルタイムで使用するために修正されたカーネルが解決策になる可能性があります。
サーバーで私がすることは、手動で他のプロセスに仕事をさせることです-サーバーを「呼吸」させるために一時停止を含めます:
find . -name "*.gif" > files
split -l 100 files files.
for F in files.* do
cat $F | xargs rm
sleep 5
done
これは、100ファイルごとに5秒待機します。かなり時間がかかりますが、顧客は遅延に気付かないはずです。
rm *
、それが拡大し*
、ファイル名のすべての行にし、それを渡すrm
信じられないほど愚かだそれ?。なぜでしょうシェルワイルドカードを展開しますか?
*
かどうかを判断できず/*
、ユーザーのそのような決定に疑念を抱きます。
削除するファイルの数が残されているファイルの数を大幅に上回っている場合、削除するファイルのツリーをたどってすべてのファイルシステムの更新を行うのが最も効率的なアプローチではない可能性があります。(不必要な参照カウントのメモリ管理を行い、1つのステップで不要なものをすべてゴミに変えてから、クリーンアップできる範囲をスイープするのではなく、大きなツリー内のすべてのオブジェクトを参照して参照を削除することに似ています)
つまり、別のボリュームに保持されるツリーの部分を複製します。元のボリュームに新しい空のファイルシステムを再作成します。保持されたファイルを元のパスにコピーして戻します。これは、ガベージコレクションをコピーすることに漠然と似ています。
ある程度のダウンタイムが発生しますが、継続的な悪いパフォーマンスとサービスの中断よりも優れている可能性があります。
あなたのシステムや状況では実用的ではないかもしれませんが、これが道である明白なケースを想像するのは簡単です。
たとえば、ファイルシステム内のすべてのファイルを削除したいとします。1つずつ再帰および削除するポイントは何でしょうか?マウントを解除し、パーティションの上部で「mkfs」を実行して空のファイルシステムを作成します。
または、半ダースの重要なファイルを除くすべてのファイルを削除したいとしますか?そこから半ダースを取得し、...「mkfs」の上に。
最終的には、停止する必要のあるファイルが十分にある場合、いくつかの損益分岐点があり、ダウンタイムなどの他のコストを考慮して、再帰的な削除を行う方が安くなります。
やってみました:
find . -name "*.gif" -exec rm {} +
末尾の+記号により、findは実行される単一のrmコマンド用のファイルをさらに含みます。詳細については、この質問を確認してください。
-delete
)必ずしもそこにある必要はありません