5

数百万の小さなファイル (平均で約 50 KB) の大容量ストレージで、20 分以上経過したファイルを自動プルーニングするための適切な戦略は何ですか? それらを書き、Web サーバーからアクセスする必要があります。

私は現在 ext4 を使用しており、削除中 (cron でスケジュール) に HDD の使用率が 100% まで急増し、負荷を作成するプロセスとして [flush-8:0] が表示されます。この負荷は、サーバー上の他のアプリケーションに干渉します。削除がない場合、最大 HDD 使用率は 0 ~ 5% です。状況は、ネストされたディレクトリ構造とネストされていないディレクトリ構造で同じです。最悪の部分は、負荷のピーク時の一括削除が挿入の速度よりも遅いように見えることです。そのため、削除する必要があるファイルの量はますます大きくなります。

スケジューラー (deadline、cfq、noop) を変更しようとしましたが、役に立ちませんでした。また、スクリプトを削除するようにioniceを設定しようとしましたが、どちらも役に立ちませんでした。

MongoDB 2.4.3 で GridFS を試してみましたが、うまく機能しますが、古いファイルを大量に削除するときはひどいものです。ジャーナリングをオフにして(nojournal)、削除と挿入の両方の書き込み確認なし(w = 0)でMongoDBを実行しようとしましたが、役に立ちませんでした。削除が行われていない場合にのみ、高速かつスムーズに機能します。

また、innodb_buffer_pool=2GB、innodb_log_file_size=1GB、innodb_flush_log_on_trx_commit=2 を使用するように InnoDB エンジンを設定して、MySQL 5.5、BLOB 列、InnoDB テーブルにデータを保存しようとしましたが、パフォーマンスは悪く、HDD 負荷は常に 80% でした。 100% (予想されますが、試してみる必要がありました)。テーブルは BLOB 列、DATETIME 列、および CHAR(32) latin1_bin UUID のみを使用し、UUID 列と DATETIME 列にインデックスを使用していたため、最適化の余地がなく、すべてのクエリでインデックスが使用されていました。

pdflush 設定 (一括削除中に負荷を作成する Linux フラッシュ プロセス) を調べましたが、値を変更しても何の役にも立たなかったため、デフォルトに戻しました。

自動プルーニング スクリプトを 1 秒ごと、1 分ごと、5 分ごと、30 分ごとにどれだけ頻繁に実行しても、いずれにしてもサーバーが大幅に中断されます。

iノード値を保存しようとしましたが、削除するときは、最初にiノード番号でソートして古いファイルを順番に削除しましたが、役に立ちませんでした。

CentOS 6を使用。HDDはSSD RAID 1です。

自動プルーニングのパフォーマンスの問題を解決する、私のタスクにとって適切で賢明なソリューションは何でしょうか?

4

2 に答える 2

2

データとメタデータの両方をディスク上で破棄する必要があるため、削除は一種のパフォーマンスの厄介な問題です。

それらは本当に別々のファイルである必要がありますか?古いファイルは本当に削除する必要がありますか、それとも上書きしても問題ありませんか?

これらの質問の 2 番目の質問に対する答えが「いいえ」の場合は、次のことを試してください。

  • 大まかに年齢別にソートされたファイルのリストを保持します。ファイルサイズごとにチャンクするかもしれません。
  • 新しいファイルに書き込みたい場合は、古いファイルを見つけてください。古いファイルは、置き換えるファイルよりも大きいことが望ましいです。古いファイルを吹き飛ばす代わりにtruncate()、適切な長さにしてからその内容を上書きします。old-files リストを必ず更新してください。
  • 時々明示的に置き換えられていない本当に古いものをクリーンアップします。
  • これらのファイルに索引を付けると有利な場合があります。tmpfs実際のファイル システムへのシンボリック リンクをすべて使用してみてください。

ファイルを扱いやすいサイズのサブディレクトリに分割することで、このスキームでパフォーマンス上の利点が得られる場合と得られない場合があります。

複数のものを同じファイルに入れても問題ない場合:

  • 同じサイズのファイルの配列にそれぞれをオフセットとして格納することにより、同じサイズのファイルをまとめて保持します。すべてのファイルが 32k または 64k の場合、1 つのファイルを 32k チャンクでいっぱいにし、1 つのファイルを 64k チャンクでいっぱいにします。ファイルのサイズが任意の場合は、次の 2 の累乗に切り上げます。
  • ここで、各ファイルがどの程度古いかを追跡することにより、遅延削除を行うことができます。書き込もうとしているときに何かが古くなっている場合は、ファイルの末尾に追加するのではなく、上書きしてください。

別の考え:truncate()すべてのファイルを inode 順に長さ 0 に ing してから ing することで、パフォーマンス上の利点が得られunlink()ますか? 無知なため、これが実際に役立つかどうかを知ることはできませんが、データが一緒にゼロになり、メタデータが同じように一緒に書き込まれるようです.

さらに別の考え: XFS の書き込み順序モデルは、ext4 with よりも弱いdata=orderedです。XFSで十分に高速ですか?

于 2013-04-29T07:35:36.520 に答える
2

何百万ものファイルを一括削除するとパフォーマンスの問題が発生する場合は、すべてのファイルを一度に「削除」することでこの問題を解決できます。ファイルシステム操作(「削除」や「切り捨て」など)を使用する代わりに、古いファイルシステムの代わりに新しい(空の)ファイルシステムを作成できます。

このアイデアを実装するには、ドライブを 2 つ (またはそれ以上) のパーティションに分割する必要があります。1 つのパーティションがいっぱいになった後 (または 20 分後)、最初のパーティションを読み取り専用に使用しながら、2 番目のパーティションへの書き込みを開始します。さらに20分後、最初のパーティションをアンマウントし、そこに空のファイルシステムを作成し、再度マウントしてから、最初のパーティションへの書き込みを開始し、2番目のパーティションを読み取り専用に使用します.

最も簡単な解決策は、2 つのパーティションのみを使用することです。しかし、この方法ではディスク容量をあまり効率的に使用できません。同じドライブに保存できるファイルが 2 倍少なくなります。より多くのパーティションを使用すると、スペース効率を高めることができます。

何らかの理由ですべてのファイルを 1 か所にまとめる必要がある場合は、ファイルへのtmpfsリンクを各パーティションに保存するために使用します。これには、 から数百万のリンクを一括削除する必要がありますがtmpfs、ファイルの内容ではなくリンクのみを削除する必要があるため、パフォーマンスの問題が緩和されます。また、これらのリンクは SSD からではなく、RAM からのみ削除されます。

于 2013-04-29T12:22:55.223 に答える