1. ホーム
  2. client-server

[解決済み】クライアント・サーバー同期パターン/アルゴリズム?

2022-04-02 08:55:57

質問

クライアントとサーバーの同期パターンがあるはずだという気がしています。しかし、私は完全にグーグルアップに失敗しました。

状況は非常にシンプルです。サーバーは中心的なノードで、複数のクライアントが接続して同じデータを操作します。データはアトム単位に分割でき、競合が発生した場合はサーバーにあるものが優先されます(ユーザーが競合の解決に巻き込まれるのを避けるため)。データが大量になる可能性があるため、部分的な同期が望ましい。

このような状況に対応するためのパターンやグッドプラクティスはありますか?

以下は、私が今考えている解決方法です。 データと並行して、すべてのトランザクションのタイムスタンプを持つ変更ジャーナルを保持します。 クライアントが接続すると、最後のチェック以降のすべての変更を統合した形で受け取ります(サーバーはリストを調べて、削除に続く追加を削除し、各アトムについて更新をマージします)。 これで、最新の状態になった。

代替案としては、各レコードの更新日を保持し、データ削除を実行する代わりに、削除済みとしてマークするだけでよいでしょう。

いかがでしょうか?

解決方法は?

分散型変更管理の仕組みを見ておくとよいでしょう。 SVNやCVSなど、差分作業を管理するリポジトリを見てみましょう。

ユースケースがいくつかあるんですね。

  • 変更を同期させる。 変更ログ(または差分履歴)アプローチはこれに適しています。 クライアントがサーバーに差分を送信し、サーバーが差分を集約してクライアントに配布します。 これが典型的なケースです。 データベースはこれをトランザクション・レプリケーションと呼んでいます。

  • クライアントが同期を失った。 バックアップ/リストアによるものか、バグによるものかのどちらかです。 この場合、クライアントは、差分を経ずにサーバーから現在の状態を取得する必要があります。 これは、マスターからディテールへのコピーであり、デルタやパフォーマンスは関係ない。 これは一回限りのことです。クライアントは壊れています。これを最適化しようとせず、信頼できるコピーを実装するだけでいいのです。

  • クライアントが怪しい この場合、クライアントとサーバーを比較して、クライアントが最新かどうか、何か差分が必要かを判断する必要があります。

データベース(とSVN)のデザインパターンに従って、すべての変更に連番を振るべきです。 そうすれば、クライアントは同期を試みる前に、些細なリクエスト("どのリビジョンを持つべきか?")を行うことができます。 そして、その場合でも、クライアントとサーバーが処理するクエリ("2149年以降のすべての差分)は、とてもシンプルです。