web-dev-qa-db-ja.com

ssh経由で多数のファイルをコピーする

(sshfsを使用して)ssh上にリモートサーバーをマウントします。多数のファイルをリモートサーバーからローカルにコピーしたい:

cp -rnv /mounted_path/source/* /local_path/destination

このコマンドは、既存のファイルを上書きしない再帰コピーを実行します。しかし、コピープロセスはかなり遅いです。ファイルを順番にコピーしないことに気づきました。だから私の質問は:複数の端末を開いて上記の同じコマンドを実行することでコピープロセスを高速化できますか?コピープロセスは、他のプロセスによってコピーされたファイルを上書きしないほど賢いですか?

1
Tu Bui

…述べられているように元の質問に答えるために…

ここで議論することが2つあります。

SSHFSの使用

SSHFSは、SSHプロトコルのSFTP「サブシステム」を使用して、リモートファイルシステムをローカルにマウントされているかのように見せます。

ここで重要なことは、SSHFSが低レベルsyscalls を比較的高レベルのSFTPコマンドに変換してから変換することに注意することです。 SFTPサーバーによってサーバー上で実行されるsyscallに変換され、その結果がクライアントに返送され、逆方向に変換されます。

このプロセスにはいくつかの速度低下の原因があります。

  • ファイルに対する個別の操作には個別のシステムコールがあり、クライアントが発行した順序で実行されます。たとえば、クライアントはファイルの情報をstat(2)- sし、次にそのファイルをopen(2)- sし、そのデータを読み取ります—連続して複数のread(2)呼び出しを実行し、次に、最後にファイルをclose(2)- sします。これらのすべてのsyscallは、SFTPコマンドに変換され、サーバーに送信され、そこで処理されて、結果がクライアントに返送され、変換されます。
  • SSHFSは、「先読み」(クライアントから要求されたよりも多くのデータを投機的に読み取る)などの特定の巧妙なハックを実装しているように見えますが、それでも、各システムコールはサーバーへの往復になります。つまり、データをサーバーに送信し、サーバーが応答するのを待ってから、応答を処理します。 IIUC、SFTPは「パイプライン」を実装していません。これは、コマンドが完了する前にコマンドを送信する操作モードであるため、基本的に各システムコールです。 技術的に可能 このような処理をある程度行うことは可能ですが、sshfsはそれを実装していないようです。

    クライアントマシン上の各syscallcpが行うIOWは、サーバーへの要求に変換され、サーバーが応答するのを待ってから、その応答を受信します。

複数のcp -nプロセスが並行して実行されます

複数のcp -nプロセスを使用してファイルを並行してコピーしてもよいかどうかという質問に対する答えは、いくつかの考慮事項によって異なります。

まず、それらがすべて同じSSHFSマウントで実行される場合、複数のcpによって発行されるすべてのsyscallが実行するため、明らかにスピードアップはありません。最終的に同じSFTPクライアント接続にヒットし、上記の理由によりシリアル化されます。

次に、distinctSSHFSマウントポイント上で実行されているcp -nのいくつかのインスタンスを実行することは、ネットワークスループットとターゲットファイルシステムの下のメディア/メディアによるI/Oスループット。この場合、SSHFSはサーバーでロックを使用しないため、cp -nのさまざまなインスタンスは、単に互いのつま先を踏まないように、個別のディレクトリ階層で動作する必要があることを理解することが重要です。

異なる/より賢明なアプローチ

まず、tarcpioまたは別のストリーミングアーカイバによって作成されたデータストリームをパイプ処理してリモートで処理すると、ファイルシステム操作のすべてのラウンドトリップが回避されるという利点があります。ローカルアーカイバがストリームを作成します。ソースファイルシステムのI/Oスループットが許す限り速く、ネットワークが許す限り速く送信します。 removeアーカイバは、ストリームからデータを抽出し、可能な限り高速にローカルファイルシステムを更新します。基本的な「コマンド」を実行するためのラウンドトリップは含まれません。このパイプラインで最も遅いI/Oポイントで可能な限り速く進みます。速く行くことは単に不可能です。

次に、rsyncを使用して提案された別の回答で、次の理由でその提案を拒否しました

rsyncはファイルをチェックサムする必要があるため、低速です。

これは単に間違っています。 rsyncのマニュアルページを引用するには:

-c--checksum

これにより、rsyncがファイルが変更され、転送が必要かどうかを確認する方法が変わります。このオプションがない場合、rsyncは「クイックチェック」を使用します。これは(デフォルトで)各ファイルのサイズと最終変更時刻が送信者と受信者の間で一致するかどうかをチェックします。このオプションはこれを変更して、サイズが一致する各ファイルの128ビットチェックサムを比較します。

そして

-I--ignore-times

通常、rsyncは、すでに同じサイズで同じ変更タイムスタンプを持つファイルをスキップします。このオプションは、この「クイックチェック」動作をオフにして、すべてのファイルを更新します。

--size-only

これにより、転送が必要なファイルを検索するためのrsyncの「クイックチェック」アルゴリズムが変更され、サイズまたは最終変更時刻が変更されたファイルを転送するデフォルトから、サイズが変更されたファイルを検索するように変更されます。これは、タイムスタンプを正確に保持しない可能性のある別のミラーリングシステムを使用した後にrsyncの使用を開始するときに役立ちます。

そして最後に

--existingレシーバーでの新しいファイルの作成をスキップ

--ignore-existingレシーバーに存在するファイルの更新をスキップ

あれは、

  • デフォルトでは、rsyncはファイルの内容をハッシュして、ファイルが変更されたかどうかを確認しません。
  • cp -nとまったく同じように動作するように指示できます。つまり、ファイルがリモートに存在するだけの場合は、ファイルの更新をスキップします。
3
kostix

tarまたはcpioの2つのインスタンスをSSHチャネル経由で使用することをお勧めします。

$ tar -C src/path -cf - . | ssh user@server tar -C dst/path -xf -

このアプローチには、SSHFSと比較して、単一のデータフローで「フルパイプ」を消費するという利点があります(インタラクティブ性が必要な場合は、間に| pvを挿入して、どのように動作するかを確認することもできます)。 (およびSFTP)これは、サーバーとクライアントの間で多くのラウンドトリップを実行します。

ここで重要なのは、SSHは単に「リモートでログインする」ことではなく、多くの人がそう思っていることです。つまり、任意のコマンドをリモートで実行することです。その標準I/OストリームをローカルSSHクライアントインスタンスに接続している間。


これがセキュリティで保護されたLANまたはその他の制御された環境で発生する場合は、SSHを破棄し、ncまたはsocatインスタンスのペアを使用するのが最善であることに注意してください。サーバーでリッスンし、サーバーで送信します。クライアント。このアプローチでは、データの暗号化にCPUサイクルを費やさないため、ソースFS、ネットワーク、および宛先FSの3つのコンポーネントのいずれかでI/Oによって制限される可能性があります。

2
kostix

いいえ、コピープロセスは、他のプロセスによってコピーされたファイルを上書きしないようにするのは賢明ではありません。複数のコマンドを実行して同じファイル/フォルダーをコピーすることはお勧めできません。

ソースマシンとターゲットマシンが遠すぎてネットワークが遅い場合、多くのことができない場合があります。これが post で、SSHFSが遅い理由を説明します。

1
Khaled

rsyncフラグとavPフラグを使用することをお勧めします。例:

rsync -avP <Source>  <Destination>
1
Ketan Patel