1

私は、クライアントと (http) サーバーの間でファイル構造を同期する必要があるアプリケーションを作成中です。

ファイル構造は基本的にファイル パスのリストであり、各パスは 1 つ以上のデータ ブロック ID (実際のデータ ブロックへの 256 ビット参照) に接続された文字列です。データブロックは複数のファイルから参照できるため、パスと ID の間に nm の関係があります。現時点では、ID を持つパスのリストにすぎませんが、同期に必要な場合は、パスが表すツリー構造に簡単に変換できます。

このデータを効率的に同期できるデータ構造を探しています。主に次の 2 つの目標を達成します。

  1. 1 つのファイルの変更によって、クライアントがファイル構造全体をサーバーに送信することを強制するべきではなく、その小さなサブセットのみを送信する必要があります。
  2. 多くのファイルが変更された場合、これらの変更はまとめてグループ化する必要があります。たとえば、1000 の変更がサーバーへの 1000 の要求にならないようにします。

ご覧のとおり、目標は少し矛盾しているため、それらの間の適切な中間点を見つけるものを探しています. 2 番目の目標は、複数の変更を 1 つの http 要求にグループ化することで簡単に達成できますが、サーバーが必要とする処理 (HTTP 要求によって要求されたすべての変更を解析するため) は、コンピューティングに関して非常に安価である必要があります。

また、サーバー上で同じ構造を同期している複数のクライアントが存在する可能性があることにも言及する必要があります。したがって、1 つのクライアントによる変更を簡単に検出して、それを別のクライアントに同期させることができなければなりません (つまり、サーバーへのアップロードだけではありません)。

私は確かにこのようなことをする最初の人ではないので、利用可能ないくつかのスマートなソリューションがあると思います. たとえば、メタデータを同期する場合、Dropbox と Subversion の両方に同様の要件があると思います。彼らがそれをどのように実装したか知っている人はいますか?

4

2 に答える 2

2

rsyncを使用しない理由はありますか? プログラムで制御する必要がある場合は、librsyncがあります。

Subversion のソース コードは公開されているので、確認できます。また、Mercurial には、トラフィックを最小限に抑えるための非常にスマートなワイヤ プロトコルがあることも知っています。

于 2009-11-25T20:23:48.737 に答える
1

トランザクションログを使用してこれを解決することにしました。各クライアントは、ツリーへのすべての変更をトランザクション ログに保存し (保持するツリーのローカル データベースに加えて)、サーバーと定期的に同期します。ログは、file->datablock-id とタイムスタンプを含むエントリの単なるリストです。

ログがサーバーに送信されると、クライアントから削除されます。ログをアップロードする前に、他のクライアントによって同じツリーに書き込まれたログも要求されます。これらのログはローカル ツリーにマージされます。

ログ自体は、Azure Blob Storage を使用してサーバーに保存されます。サーバーは、ログから古いエントリを定期的に削除できます (エントリが大きくなった場合)。

このようにして、クライアントは効率的に変更を相互に通信できますが、サーバーは要求ごとに高価な処理を行う必要がありません。

于 2009-11-26T22:36:11.680 に答える