web-dev-qa-db-ja.com

変更されていない巨大なディレクトリの高速rsync

サーバーのバックアップにはrsyncを使用します。

残念ながら、一部のサーバーへのネットワークは低速です。

巨大なディレクトリで何も変更されていないことをrsyncが検出するには、最大5分かかります。これらの巨大なディレクトリツリーには、多数の小さなファイル(約80kファイル)が含まれています。

私は、rsyncクライアントが80kのファイルごとにデータを送信すると思います。

ネットワークが遅いので、各ファイルに関する情報を8万回送信しないようにしたいと思います。

Rsyncにサブディレクトリツリーのハッシュサムを作成するように指示する方法はありますか?

この方法では、rsyncクライアントは巨大なディレクトリツリーに対して数バイトしか送信しません。

更新

これまでの私の戦略は、rsyncを使用することです。ただし、ここで別のツールが適している場合は、切り替えることができます。両方(サーバーとクライアント)は私の管理下にあります。

pdate2

1つのディレクトリに80kファイルありますtree。各単一のディレクトリには、2kを超えるファイルまたはサブディレクトリはありません

pdate

ネットワークの遅さの詳細:

time ssh einswp 'cd attachments/200 && ls -lLR' >/tmp/list
real    0m2.645s

Tmp/listファイルのサイズ:2MByte

time scp einswp:/tmp/list tmp/
real    0m2.821s

結論:scpは同じ速度です(驚きはありません)

time scp einswp:tmp/100MB tmp/
real    1m24.049s

速度:1.2MB /秒

13
guettli

いくつかの無関係なポイント:

80Kはたくさんのファイルです。

1つのディレクトリに80,000ファイル?デフォルトでは、そのような状況を処理するオペレーティングシステムやアプリはありません。あなたはたまたまrsyncでこの問題に気づきます。

Rsyncのバージョンを確認する

最新のrsyncは、大規模なディレクトリを以前よりもはるかにうまく処理します。最新バージョンを使用していることを確認してください。

古いrsyncでも、大きな遅延のあるリンクで大きなディレクトリをかなりうまく処理します...しかし、80kファイルは大きくありません...それは巨大です!

つまり、rsyncのメモリ使用量は、ツリー内のファイル数に正比例します。大きなディレクトリには大量のRAMが必要です。遅いのは、RAMが不足していることが原因である可能性があります。メモリ使用量を監視しながらテストを実行してください。Linuxは、残りのRAMをディスクキャッシュなので、RAMが不足している場合は、ディスクキャッシュが少なくなります。RAMが不足し、システムがswapの使用を開始すると、パフォーマンスが著しく低下します。

--checksumが使用されていないことを確認してください

--checksum(または-c)では、すべてのファイルのすべてのブロックを読み取る必要があります。変更時間(inodeに格納されている)を読み取るだけのデフォルトの動作でおそらく問題はないでしょう。

ジョブを小さなバッチに分割します。

Gigasync のようないくつかのプロジェクトがあります。これは、Perlを使用してディレクトリツリーを再帰し、rsyncで転送するファイルの小さめのリストを作成してワークロードを切り詰めます。

追加のディレクトリスキャンはかなりのオーバーヘッドになりますが、多分それは正味の利益になるでしょう。

この状況では、OSのデフォルトは作成されません。

Linux/FreeBSD/etcをすべてデフォルトで使用している場合、すべてのアプリケーションのパフォーマンスはひどいものになります。デフォルトでは、サイズの大きいキャッシュでRAM=を無駄にしないように、より小さなディレクトリを想定しています。

大きなディレクトリをより適切に処理するようにファイルシステムを調整します。 大きなフォルダーサイズは遅くなりますかIOパフォーマンス?

「なめキャッシュ」を見る

BSDライクなオペレーティングシステムには、iノードへの名前の検索を高速化するキャッシュ(「namei」キャッシュ)があります。各ディレクトリには、nameiキャッシュがあります。小さすぎると、最適化以上の障害となります。 rsyncは各ファイルでlstat()を実行しているため、80kファイルのすべてに対してiノードがアクセスされています。これは、キャッシュを破壊している可能性があります。システムでファイルディレクトリのパフォーマンスを調整する方法を調べてください。

別のファイルシステムを検討する

XFSは、より大きなディレクトリを処理するように設計されています。参照 単一ディレクトリ内のファイルシステムの多数のファイル

たぶん、5分がベストです。

読み込まれているディスクブロックの数を計算し、ハードウェアがその数のブロックを読み取ることができると予想される速度を計算します。

多分あなたの期待は高すぎます。変更されたファイルなしでrsyncを実行するために読み取る必要のあるディスクブロックの数を考慮してください。各サーバーはディレクトリを読み取り、ファイルごとに1つのiノードを読み取る必要があります。何もキャッシュされていないとしましょう。まあ、80kのファイルがおそらくキャッシュを破壊したからです。計算を簡単にするために80kブロックであるとしましょう。これは約40Mのデータで、数秒で読み取れるはずです。ただし、各ブロック間にディスクシークが必要な場合は、さらに時間がかかる可能性があります。

したがって、約80,000のディスクブロックを読み取る必要があります。あなたのハードドライブはどれくらい速くそれを行うことができますか?これはランダムなI/Oであり、長い線形読み取りではないことを考えると、5分はかなり優れている可能性があります。これは1 /(80000/600)、または7.5msごとに読み取られるディスクです。ハードドライブの速度は遅いですか?モデルにより異なります。

類似のものに対するベンチマーク

それについて考える別の方法はこれです。変更されたファイルがない場合、ls -Llrは同じ量のディスクアクティビティを実行しますが、ファイルデータ(メタデータのみ)を読み取ることはありません。実行にls -Llrがかかる時間は上限です。

  • Rsync(ファイルが変更されていない)はls -Llrより大幅に遅いですか?その後、rsyncに使用しているオプションを改善できます。たぶん-cが有効になっているか、ディレクトリとメタデータ(inodeデータ)以外の情報を読み取るフラグがあります。

  • Rsync(ファイルが変更されていない)はls -Llrとほぼ同じ速度ですか?次に、rsyncをできる限り調整しました。 OSのチューニング、RAMの追加、より高速なドライブの取得、ファイルシステムの変更などを行う必要があります。

開発者と話す

80kファイルは単に悪いデザインです。このような大きなディレクトリを適切に処理するファイルシステムやシステムツールはほとんどありません。ファイル名がabcdefg.txtの場合は、abdc/abcdefg.txtに保存することを検討してください(繰り返しに注意してください)。これはディレクトリを小さなディレクトリに分割しますが、コードに大きな変更を加える必要はありません。

また、...データベースの使用を検討してください。ディレクトリに80kのファイルがある場合、開発者が本当に必要なのはデータベースであるという事実に対処している可能性があります。 MariaDBまたはMySQLまたはPostgreSQLは、大量のデータを格納するためのはるかに優れたオプションです。

ねえ、5分で何が悪いの?

最後に、5分間は本当に悪いのでしょうか。このバックアップを1日に1回実行する場合、5分はそれほど多くの時間ではありません。はい、スピードが大好きです。ただし、顧客にとって5分で「十分」であれば、それで十分です。書面によるSLAがない場合は、ユーザーとの非公式なディスカッションで、バックアップの速度をユーザーが予測する方法を確認してください。

パフォーマンスを改善する必要がない場合は、この質問をしなかったと思います。ただし、顧客が5分間満足している場合は、勝利を宣言し、努力が必要な他のプロジェクトに進みます。

更新:議論の結果、ボトルネックがネットワークであることが判明しました。私はあきらめる前に2つのことをお勧めします:-)。

  • 圧縮により、パイプからより多くの帯域幅を絞り込もうとします。ただし、圧縮にはより多くのCPUが必要になるため、CPUが過負荷の場合、パフォーマンスが低下する可能性があります。 -zを使用して、または使用せずにrsyncを試し、圧縮を使用して、または使用せずにsshを構成します。 4つすべての組み合わせの時間を計って、それらのいずれかが他よりも大幅に優れているかどうかを確認します。
  • ネットワークトラフィックを監視して、一時停止がないかどうかを確認します。一時停止がある場合は、一時停止の原因を見つけて最適化できます。 rsyncが常に送信している場合は、本当に限界に達しています。選択肢は次のとおりです。
    • より高速なネットワーク
    • rsync以外のもの
    • 移動元と移動先を近づけます。それができない場合は、ローカルマシンにrsyncしてから、実際の宛先にrsyncできますか?最初のrsync中にシステムを停止する必要がある場合、これを行うことには利点があるかもしれません。
36
TomOnTime

いいえ、それはrsyncでは不可能であり、別の点では非常に非効率的です。

通常、rsyncはファイルの変更日とファイルサイズのみを比較します。あなたのアプローチでは、変更されたディレクトリを見つけるためにallファイルの内容を(ローカルシステムとリモートシステムで)2回読み取り、チェックサムします。

2
Sven

多数のファイル(ほとんど変更されていないファイル)の同期の場合、ソースパーティションと宛先パーティションにnoatimeを設定することも価値があります。これにより、変更されていないファイルごとにディスクへの書き込みアクセス時間が節約されます。

2
Andy Beverley

Lsyncdを試すこともできます。これは、ファイルシステムで変更が検出され、変更されたサブディレクトリだけが検出された場合にのみrsyncします。まともなサーバー上の最大200万のファイルを含むディレクトリに使用しています。

2
Juanga Covas

サーバー側でデーモンモードでrsyncを使用して、リスト/チェックサムプロセスを高速化します。

これは暗号化されていませんが、リストのパフォーマンス向上を失うことなくトンネリングできる可能性があることに注意してください。

また、sshではなくrsyncで圧縮を行うと、パフォーマンスが向上します。

1
Gringo Suave