0

約 10 種類のオブジェクトを持つアプリがあります。各タイプのオブジェクト インスタンスが数千になる可能性があります。これらのオブジェクトのリストは、異なるマシンで実行されているアプリ間で同期を維持する必要があります。オブジェクトが追加、変更、または削除された場合、それを他のマシンに伝達する必要があります。

これはスター トポロジになります。中央のマスターがあり、残りはクライアントです。

私はセッションの概念を持っているので、各クライアントに関するデータを保存できます。

これに従うべき良い設計パターンはありますか?さらに良いことに、クライアント X がやってきてから何が変わったのかをコンテナーに問い合わせ、そのデルタを送信するように処理する (テンプレート ベースの?) ライブラリはありますか?

現在、すべてのオブジェクト タイプのコンテナには更新カウンタがあると考えています。何かが追加/変更/削除されると、更新カウンターがインクリメントされ、変更されたオブジェクトがその値でタグ付けされます。各クライアントは、更新を取得すると、更新カウンターの値を保存します。後で戻ってきて、更新カウンター値であるため、変更を要求します。最後に、削除は廃棄レコードとして保持されます (ただし、いつ削除するかは正確にはわかりません)。

これをより困難にしているのは、クライアントが中央サーバーが必ずしも知らなくても出入りできることですが、タイムアウトの概念がある可能性があると思います (サーバーがクライアントから 5 分間応答がない場合、クライアントがなくなったと見なされます)。

これは有名なパターンですか?追加の提案はありますか?

4

2 に答える 2

1

同期をどのように実装するかは、ニーズによって大きく異なります。変更をクライアントに送信する必要がありますか?それとも、クライアントがオブジェクトを使用するたびにオブジェクトが最新かどうかを確認するだけで十分ですか? Proxy パターンを使用するのはどうですか? このパターンを使用すると、オブジェクトが最新かどうかをチェックし、最新でない場合は更新し、結果を返すことができるオブジェクトのプロキシ実装を作成できます。これを行うには、マスターのオブジェクトに lastChanged タイムスタンプを設定し、クライアント オブジェクトに lastUpdated タイムスタンプを設定します。待ち時間が問題になる場合、各呼び出しでオブジェクトが最新かどうかを確認することは、おそらく良い考えではありません。変更されたオブジェクトをマスターに照会し、それらを「ダーティ」とマークする別のスレッドを用意することを検討してください。これにより、ネットワーク トラフィックも大幅に削減できます。

Observer パターンPublish/Subscribeを調べることもできます。

于 2009-09-18T15:13:53.137 に答える
0

実装が簡単でありながらかなり効率的なオプションは、オブジェクトの山を不透明なブロブとして扱い、librsync を使用してそれらを同期することです。すべての更新は、マスターからクライアントへの一方向に流れているように聞こえます。おそらく、クライアント上のオブジェクト (ファイルなど) の永続的な表現が存在します。任意のバイト シーケンスを使用できますが、この回答の残りのファイルであると想定しています。

それが機能する方法は、各クライアントが blob のローカル コピーの librsync "署名" を生成し、その署名をマスターに送信することです。シグネチャは、ブロブのサイズの約 1% です。次に、マスターは librsync を使用してその署名と現在のデータの間のデルタを計算し、デルタをクライアントに送信します。クライアントは librsync を使用してデルタをブロブのローカル コピーに適用します。

librsync API はシンプルで、署名/デルタ データ転送は比較的効率的です。

それがうまくいかない場合でも、オブジェクトごとのバージョン管理を行わなくて済むように、より手動の「デルタベース」のアプローチを取ることが有効な場合があります。マスターが変更を加えるたびに、その変更をジャーナルに記録し、何が行われ、どのオブジェクトに対して行われたかを記録する必要があります。バージョン管理はデータベース全体のレベルで行われるため、実際にはバージョン番号が各ジャーナル エントリに割り当てられます。

クライアントが接続すると、クライアントはオブジェクト コレクション全体のバージョンを送信する必要があり、サーバーはクライアントのバージョンと最新のエントリの間のジャーナルの内容で応答できます。オブジェクトのコンテンツを完全に置き換えることによって特定のオブジェクトの更新が行われる場合、各オブジェクトの最新バージョンを除くすべてを除外することにより、これを最適化できます。マスターが、どのバージョンをどのクライアントに送信したかを追跡している場合、古いジャーナル エントリをいつ安全に破棄できるかを知ることができます。それが追跡されていなくても、ヒューリスティック (おそらく年齢) に従って古いジャーナル エントリを破棄することができ、最後のバージョンが最も古いジャーナル エントリよりも古いクライアントからの接続を受信した場合は、次のようにする必要があります。オブジェクトのセット全体をそのクライアントに送信します。

于 2009-10-16T14:37:19.817 に答える