web-dev-qa-db-ja.com

複数のエンティティ間でデータを同期するための最も賢くて簡単なアプローチは何ですか?

多くのコンピューター、モバイルデバイス、またはWebサービスがデータを共有したり、ハブのように機能したりする今日の世界では、同期がより重要になります。同期するソリューションは最も快適なソリューションではないことは誰もが知っているので、まったく同期しないことをお勧めします。

複数のエンティティ間で同期するための同期ソリューションをどのように実装するのか、まだ興味があります。変更された日付フィールドまたはハッシュを比較して最新のデータを使用したり、競合が発生した場合に使用するものをユーザーに選択させたりするなど、すでに多くの異なるアプローチがあります。もう1つのアプローチは、競合するデータを自動的にマージしようとすることです(マシンはユーザーの意味を推測できないため、私の意見ではそれほど賢くはありません)。

とにかく、同期の実装を開始する前に答える必要がある同期に関連するいくつかの質問があります。

  • 最新のデータは何ですか?それをどのように表現したいですか?
  • 競合が発生した場合はどうすればよいですか?マージ?プロンプトを表示して、ユーザーに何をすべきかを尋ねますか?
  • 一貫性のない状態になった場合はどうすればよいですか(たとえば、不安定なモバイルネットワーク接続による切断)?
  • 一貫性のない状態になりたくない場合はどうすればよいですか?
  • 中断された現在の同期を再開するにはどうすればよいですか?
  • データストレージを処理するにはどうすればよいですか(たとえば、WebサービスのMySQLデータベース、iPhoneのCore Data、および多くのグルーコードなしでデータをマージ/同期するにはどうすればよいですか?)
  • 同期中に発生するユーザーからの編集(バックグラウンドで実行されるため、UIがブロックされない)をどのように処理する必要がありますか?
  • 変更を伝播する方法と方向(たとえば、ユーザーが自分のコンピューターで「Foo」エントリを作成して同期しない、外出先で別の「Foo」エントリを作成する、両方のデバイスを同期しようとするとどうなるか) )?ユーザーは、一意のIDが異なる2つの「Foo」エントリを持ちますか?ユーザーのエントリは1つだけですが、どれですか?
  • 階層データがある場合、同期をどのように処理する必要がありますか?トップダウン?一気飲み?すべてのエントリをアトミックに処理しますか、それともスーパーノードのみを調べますか?物事を単純化しすぎることと、実装に多くの時間を費やすこととの間のトレードオフはどれくらいですか?

他にもたくさんの質問がありますので、十分に刺激を受けられることを願っています。同期はかなり一般的な問題です。優れた用途の広い同期アプローチが見つかったら、最初から考え始めるよりも、具体的なアプリケーションに適用する方が簡単なはずです。同期を解決(または正常に解決)しようとするアプリケーションはすでにたくさんあることを認識していますが、それらはすでにかなり具体的であり、一般的な同期アプローチに対して十分な答えを提供していません。

45

私が働いている場所では、ユーザーがインターネットにアクセスできない場所でラップトップで作業できるように、メイン(Web)アプリケーションの「オフライン」バージョンを開発しました(これらの場所が実際にいくつ存在するかはわかりません)最近ですが、そう言われています;))。ユーザーがメインサイトに戻ったら、オフラインで入力したデータをメインアプリケーションと同期する必要があります。

だから、あなたの質問に答えるために:

  • 最新のデータは何ですか?それをどのように表現したいですか?

すべてのテーブルにLAST_UPDATED_DATE列があります。サーバーは同期がいつ行われるかを追跡するため、オフラインアプリケーションが同期を要求すると、サーバーは「ねえ、この日付以降に変更されたデータのみを教えてください」と言います。

  • 競合が発生した場合はどうすればよいですか?マージ?プロンプトを表示して、ユーザーに何をすべきかを尋ねますか?

私たちの場合、オフラインアプリケーションは、すべてのデータの比較的小さなサブセットしか更新できません。各レコードが同期されると、それがこれらのケースの1つであるかどうかを確認し、同期されている場合は、オンラインとオフラインの両方でレコードのLAST_UPDATED_DATEを比較します。日付が異なる場合は、値もチェックします(両方が同じ値に更新されても、競合は発生しないため)。競合がある場合は、差異を記録し、少なくとも1つの競合があることを示すフラグを設定して、残りの詳細のチェックを続行します。プロセスが終了すると、「isConflict」フラグが設定されている場合、ユーザーは違いを表示する特別なページに移動し、どのデータが「正しい」バージョンであるかを判断できます。次に、このバージョンがホストに保存され、「isConflict」フラグがリセットされます。

  • 一貫性のない状態になりたくない場合はどうすればよいですか?
  • 中断された現在の同期を再開するにはどうすればよいですか?

そもそも、一貫性のない状態にならないようにしています。何らかの理由で同期が中断された場合、last_synchronisation_dateは更新されないため、次に同期が開始されると、前の(中断された)同期の開始日と同じ日付から開始されます。

  • データストレージを処理するにはどうすればよいですか(たとえば、WebサービスのMySQLデータベース、iPhoneのCore Data、および多くのグルーコードなしでデータをマージ/同期するにはどうすればよいですか?)

両方のアプリケーションで標準データベースを使用し、その間にJavaオブジェクト。オブジェクトは実際の同期プロセスのためにXMLにシリアル化され(転送を高速化するためにgzip圧縮され)、それぞれで解凍/逆シリアル化されます。終わり。

  • 同期中に発生するユーザーからの編集(バックグラウンドで実行されるため、UIがブロックされない)をどのように処理する必要がありますか?

これらの編集は同期開始日以降に行われるため、次の同期まで反対側で取得されません。

  • 変更を伝播する方法と方向(たとえば、ユーザーが自分のコンピューターで「Foo」エントリを作成して同期しない、外出先で別の「Foo」エントリを作成する、両方のデバイスを同期しようとするとどうなるか) )?ユーザーは、一意のIDが異なる2つの「Foo」エントリを持ちますか?ユーザーのエントリは1つだけですが、どれですか?

この特定のFooをどのように処理するかを決めるのはあなた次第です...つまり、Fooの主キーが何であるか、および1つのFooが別のFooと同じであるかどうかをどのように判断するかによって異なります。

  • 階層データがある場合、同期をどのように処理する必要がありますか?トップダウン?一気飲み?すべてのエントリをアトミックに処理しますか、それともスーパーノードのみを調べますか?

同期はアトミックであるため、1つのレコードが失敗すると、Subversionコミットトランザクションと同様に、プロセス全体が不完全としてマークされます。

  • 物事を単純化しすぎることと、実装に多くの時間を費やすこととの間のトレードオフはどれくらいですか?

正確にはわかりませんが、状況や同期するデータの種類/量によって異なります。プロセスの設計と実装には長い時間がかかる場合がありますが、それは可能です。

それがあなたを助けるか、少なくともあなたにいくつかのアイデアを与えることを願っています! :)

50
GaZ

おそらく「本当の質問ではない」、ここに本当の答えはありません:

分散バージョン管理システム(Mercurialやgitなど)がこれの大部分を理解していると思います。ただし、「最新の」バージョンが複数存在する可能性があること、および競合する更新を解決するために手動で解決する必要がある場合があることを人々が受け入れる必要があります。また、変更履歴全体を保持することに興味がない場合、これらのシステムにはかなりのオーバーヘッドがあります(ただし、2つのバージョンがどのように関連するかを判断するために、共通の祖先を見つけるには、もちろん最近の履歴が必要です)。

しかし、誰もが複数のデバイスやサービスにデータを分散している世界では、更新を自動的に追跡して配布する必要性が非常に緊急になり、アプリケーションで使用される一般的なファイル形式に十分なメタデータが含まれることに同意します。ある種のインテリジェントなマージ動作を促進します。ただし、競合する更新を解決する一般的な方法がないため、この動作はおそらくアプリケーションレベルで発生する必要があります。

それまでの間、iTunes-iPodのアプローチが最も簡単です。マスターライブラリは1つだけで、すべてのデバイスがそこからプルされます。明らかに、single-master-syncはすべてのシナリオで(特に複数のユーザーが関与している場合)満足のいくものではありませんが、それでも、より多くのアプリケーションがそのように動作するオプションを提供してくれれば幸いです(pet peeve:私は3台のMacを持っています、3つのiPhotoがインストールされています。写真がiPodに同期されるように、1つの専用マスターから自動的に同期される場合は改善されます)。

4
Thilo