デフォルトのオプションでマウントされたext3ファイルシステムがあります。その上にいくつかの〜100GBのファイルがあります。
そのようなファイルを削除すると、長時間(8分)かかり、大量のIOトラフィックが発生し、サーバーの負荷が増加します。
rmをそれほど混乱させない方法はありますか?
デフォルトのオプションでマウントされたext3ファイルシステムがあります。その上にいくつかの〜100GBのファイルがあります。
そのようなファイルを削除すると、長時間(8分)かかり、大量のIOトラフィックが発生し、サーバーの負荷が増加します。
rmをそれほど混乱させない方法はありますか?
回答:
最も興味深い答えは、もともと質問に関するコメントに埋もれていました。ここでは、よりわかりやすくするための第一級の回答として示します。
基本的にここからの方法は機能しなかったため、独自の方法を開発しました。ここで説明しました:http : //www.depesz.com/index.php/2010/04/04/how-to-remove-backups/ – depesz 10年4月6日15:15
このリンクは、実行可能なソリューションの探索と発見に関する非常に徹底的な分析です。
以下にも注意してください:
記事によると:
ご覧の
-c2 -n7
とおり、ioniceのオプションを使用しました。
これは事実ですが、ユーザーTafTは、混乱を避けたい場合は-c3
、-c2
「ベストエフォート」よりも「アイドル」の方が良い選択だと言います。彼は以前-c3
はバックグラウンドでビルドしており、ビルドを永遠に待たせることなく動作することがわかりました。本当にioの使用率が100%の場合-c3
、削除は完了しませんが、実際のテストに基づいて削除することを期待していません。
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
(つまり、サイズがゼロになりました)、rm -rf <file>
今すぐ消したい場合は
またはさらに良い
猫を落として # > /file/to/be/emptied
ディレクトリを適切なペースで削除するのに問題があり、プロセスがディスクをロックし、ディスクにアクセスしようとするプロセスの山を作成していたことがわかりました。ioniceは機能せず、ディスクIOの99%を使用し続け、他のすべてのプロセスをロックアウトしました。
これが私のために働いた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
私の2セント。
私はすでにこの問題を抱えています。「高速で実行する必要があるシーケンシャルスクリプトでは、プロセスは大量のファイルを削除します」..したがって、「rm」は、スクリプトの速度をIO待機/実行時間に近づけます。
そのため、より速くするために、cronごとに起動される別のプロセス(bashスクリプト)を追加しました。特定のディレクトリ内のすべてのファイルを削除するガベージコレクターのように。
次に、「rm」をmvで「ガーベッジフォルダー」に置き換えることで元のスクリプトを更新しました(名前の末尾にカウンターを追加してファイル名を変更し、衝突を回避します)。
これは私にとってはうまくいきます。スクリプトは少なくとも3倍速く実行されます。ただし、ガベージフォルダーと元のファイルが同じマウントポイント(同じデバイス)にある場合にのみ機能し、ファイルのコピーを防ぎます。(同じデバイス上のmvはrmより少ないIOを消費します)
お役に立てば幸いです。
ループファイルシステムを作成して、バックアップを保存してみてください。
# 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
プレスト!仮想ファイルシステム全体がすぐに消去されます。
mv <ファイル名> / dev / null
/ dev / nullはディレクトリではなくファイルです。ファイルをファイルに移動できないか、ファイルを上書きする危険があります。
(ループデバイスを使用して)高速ファイルシステムで特別なマウントポイントを作成し、それを使用して巨大ファイルを保存および削除します。(ファイルを削除する前にそこに移動するか、高速になるか、ファイルを削除したいときにアンマウントするだけです)
これは実用的ではないと思います。OPが必要とするよりも不必要に多くのI / Oを使用します。
/ dev / nullはディレクトリではなくファイルです。ファイルをファイルに移動できないか、ファイルを上書きする危険があります。
実際にはそれはデバイスであり、それに書き込まれたすべてのデータは破棄されるのでmv <file> /dev/null
理にかなっています
Wikipediaの無料百科事典
Unixライクなオペレーティングシステムでは、/ dev / nullまたはnullデバイスは、書き込まれたすべてのデータを破棄する(ただし、書き込み操作は成功したと報告する)特別なファイルであり、どのプロセスにもデータを提供しませんそれから読み取ります(すぐにEOFを生成します)。[1]