私はext3ファイルシステムをデフォルトのオプションでマウントしています。その上に私はいくつかの〜100GBのファイルを持っています。
このようなファイルの削除には長い時間がかかり(8分)、大量のioトラフィックが発生し、サーバーの負荷が増加します。
Rmをそれほど混乱させない方法はありますか?
最も興味深い答えは、もともと質問へのコメントに埋もれていた。ここに、それをより見やすくするためのファーストクラスの回答があります。
基本的にここからの方法は機能しなかったので、独自に開発しました。ここでそれを説明しました: http://www.depesz.com/index.php/2010/04/04/how-to-remove-backups/ – depesz Apr 6 '10 at 15:15
そのリンクは、実行可能なソリューションの探索と発見の信じられないほど徹底的な分析です。
また注意してください:
記事は言う:
ご覧のとおり、私は
-c2 -n7
オプションをioniceに使用しましたが、これは正気のようです。
これは本当ですが、ユーザーTafTは、中断を望まない場合は-c3
'best-effort'よりも-c2
'idle'の方が適していると述べています。彼は-c3
を使用してバックグラウンドでビルドしており、ビルドを永遠に待たせることなくうまく機能することがわかりました。実際に100%のio使用率がある場合、-c3
は削除を完了させませんが、実際のテストに基づいて、それが期待どおりのものであるとは期待していません。
エクステントまたはエクステントを使用するその他の最新のファイルシステムにアップグレードします。 ext3はエクステントではなく間接ブロックスキームを使用するため、大きなファイルを削除することは必然的に多くの作業を伴います。
ionice を試すことができます。速くはなりませんが、混乱が少なくなる可能性があります。
効率の観点から、ファイルごとに1つのrmを使用することは、各rmにforkとexecが必要になるため、最適ではありません。
削除したいファイルを含むlist.txtがあるとすると、これはより効率的ですが、それでも遅くなります。
xargs -i rm {} < list.txt
別のアプローチは次のようになります:Nice -20 xargs -i rm {} < list.txt
(これは時間がかかりませんが、システムに大きく影響します:)
または
これがどれほど速いかはわかりませんが、
mv <file-name> /dev/null
または
(ループデバイスを使用して?)高速ファイルシステムで特別なマウントポイントを作成し、それを使用して巨大なファイルを保存および削除します。
(ファイルを削除する前にファイルを移動するか、ファイルを削除したい場合は、ファイルを削除するより高速であるか、マウントを解除するだけです)
または
cat /dev/null > /file/to/be/deleted
(これでサイズが0になったため)、それを消したい場合はrm -rf <file>
今
orさらに良い
猫を落として、ただ# > /file/to/be/emptied
私の2セント。
私はすでにこの問題を抱えています。 「高速に実行する必要がある順次スクリプトでは、プロセスは多くのファイルを削除します」..したがって、「rm」は、スクリプトの速度をIO待機/実行時間に近づけます。
そのため、処理を速くするために、cronごとに起動される別のプロセス(bashスクリプト)を追加しました。特定のディレクトリ内のすべてのファイルを削除するガベージコレクターのようなものです。
次に、元のスクリプトを更新して、「rm」をmvから「ガベージフォルダー」に置き換えます(衝突を避けるために、ファイル名の最後にカウンターを追加してファイルの名前を変更してください)。
これは私にとってはうまくいき、スクリプトは少なくとも3倍速く実行されます。ただし、ファイルのコピーを回避するために、ガベージフォルダーと元のファイルが同じマウントポイント(同じデバイス)にある場合にのみ機能します。 (同じデバイスでのmv消費量IO rmよりも少ない)
お役に立てれば幸いです。
ディレクトリを適切なペースで削除するのに問題があり、プロセスがディスクをロックしていて、ディスクにアクセスしようとするプロセスの山ができていることがわかりました。 ioniceは機能しませんでした。ディスクの99%を使い続けただけで、IOで、他のすべてのプロセスがロックアウトされました。
Python私のために働いたコードです。一度に500個のファイルを削除し、2秒の休憩を取って、他のプロセスに処理を任せてから続行します。すばらしい動作です。
import os, os.path
import time
for root, dirs, files in os.walk('/dir/to/delete/files'):
file_num = 0
for f in files:
fullpath = os.path.join(root, f)
os.remove(fullpath)
if file_num%500 == 1:
time.sleep(2)
print "Deleted %i files" % file_num
file_num = file_num + 1
ループファイルシステムを作成して、バックアップを保存することもできます。
# dd if=/dev/zero of=/path/to/virtualfs bs=100M count=1024 # 100 MB * 1024 = 100 GB
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop
次に、バックアップを消去する場合:
# umount /mnt/backups
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop
プレスト!仮想ファイルシステム全体がすぐにクリアされます。
Xargsでマルチヘッドを使用できます
find . -type f | xargs -P 30 rm -rf
ここで、30は作成するスレッドの数です。ゼロを使用している場合、システムはタスクを実行しているユーザーが使用できる最大スレッドを作成します。
また、負荷の回避策として ionice を提案するDennis Williamsonの回答は、ブロックデバイスがCFQ ioスケジューラを使用している場合にのみ機能することにも注意してください。
mv <ファイル名>/dev/null
/ dev/nullはディレクトリではなくファイルです。ファイルをファイルに移動できないか、ファイルを上書きする危険があります。
(ループデバイスを使用して?)高速ファイルシステムで特別なマウントポイントを作成し、それを使用して巨大なファイルを保存および削除します。 (ファイルを削除する前にファイルをそこに移動するか、ファイルを削除する前にファイルを移動するか、ファイルをマウント解除するだけです)
これは実用的ではないと思います。 OPが必要とするよりも不必要に多くのI/Oを使用します。