web-dev-qa-db-ja.com

モバイルアプリのデータ同期-複数のデバイス、複数のユーザー

初めてのモバイルアプリの作成を検討しています。アプリケーションのコア機能の1つは、複数のデバイス/ユーザーが同じデータにアクセスできることであり、それらすべてにCRUD権限があります。

アーキテクチャには、すべてのデータが保存される中央サーバーが含まれるべきだと思います。デバイスはAPIを使用してサーバーと対話し、データ操作(レコードの追加、レコードの編集、レコードの削除など)を実行します。

データの同期が問題になるシナリオを想像します。アプリケーションがインターネットに接続されておらず、この中央サーバーと通信できない場合に、アプリケーションが機能すると想定します。そう:

  1. ユーザーAはオフラインで、レコード#100を編集します
  2. ユーザーBはオフラインで、レコード#100を編集します
  3. ユーザーCはオフラインで、レコード#100を削除します
  4. ユーザーCがオンラインになります(おそらく、レコード#100がサーバーで削除されるはずです)
  5. ユーザーAとBはオンラインになりますが、編集したレコードは存在しません

上記と同様のあらゆる種類のシナリオが考えられます。

これは通常どのように処理されますか? MySQLを使用する予定ですが、そのような問題には適切ではないかと思っています。

43

私は現在、まったく同じ要件と問題を抱えるモバイル/デスクトップ/分散型アプリに取り組んでいます。

まず、これらの要件は、モバイルアプリ自体に固有のものではなく、切断/分散されたクライアント/サーバートランザクション(並列プログラミング、マルチスレッド、要点)に固有のものです。もちろん、それらはモバイルアプリで対処する典型的な問題です。

一般に、これはすべて要約すると、n個のクライアントに配布される潜在的なデータレコードがあり、同時に編集する可能性があるということです。必要なのは

  1. 適切なバージョン管理/ロックメカニズム、
  2. 適切な権利/アクセス管理、
  3. 適切な同期/キャッシュ戦略

(1)にはいくつかのパターンを適用できます:頻繁に使用される2つのロック戦略があります: 楽観的オフラインロック および 悲観的オフラインロック 。これらのいくつかは、 MultiVersion Concurrency Control (MVCC)などのさまざまなバージョンコントロール「パターン」で適用され、すべてのデータレコードに対してカウンター(非常に単純な「タイムスタンプ」の一種)を使用します。レコードが変更されるたびに更新されます。

(2)と(3)はそれ自体が非常に広範な問題であり、(1)とは関係なく処理する必要があります。私の経験からのいくつかのアドバイス:

  • ほとんどの問題を抽象化するクライアントサーバーテクノロジを使用します。 CouchDb などのWebテクノロジーを強くお勧めします。これは、(1)オプティミスティックオフラインロック+ MVCCを介して、(2)Web APIを介して、および(3)Httpキャッシングを介して非常によく処理します。

  • 実績のあるテクノロジーとアプローチに依存できる場合は、自分で発明しないようにしてください。既存のテクノロジー/パターンの調査と比較に費やす時間は、独自のシステムを実装するよりもはるかに優れていると思います。

  • 可能であれば、同種のテクノロジーを使用してください。 「同種」とは、同じ原則を念頭に置いて構築されたテクノロジーを意味します。 Web 2.0の使用シナリオ。例:適切なCouchDbとRESTクライアント(Web API)をローカルキャッシング戦略で使用することは、モバイルアプリでSQLを使用するよりも良い選択です。

  • MySQLはそのような使用シナリオのために明示的に作成されたものではないテクノロジであるため、MySQLの使用は強くお勧めしません。それは機能しますが、すでにWeb通信と並行性のスタイルを採用しているデータベースシステム(多くのNoSQLデータベースなど)の方がはるかに便利です。

ちなみに、私はCouchDb APIに対して動作するカスタムローカルクライアントを使用してCouchDbを解決しました。私はMSQL +(N)Hibernateの使用から切り替え、最初に正しい選択をしない(十分な調査を行わない)ために高額を支払いました。

32
Sebastian

最初に、APIとデータベース(MySQL)の両方について言及しました。 APIを使用し、データベース間で直接通信しようとしないことを強くお勧めします。後者のルートは、まったくうまく拡張されません。

検討すべき1つの良い出発点は、 Apache CouchDB を使用することです。 HTTPとJSONに基づくスキーマレスで、非常に優れたレプリケーションメカニズムを備えています。同様の問題を解決するために使用します。

CouchDBのレプリケーションメカニズムは、他のクライアントが使用するのと同じHTTP APIを使用します。つまり、本質的には、APIを介したレプリケーションを提供します。

IOSの場合、 Couchbase Liteプロジェクト を使用することをお勧めします。データの同期に非常に適しています。 Androidの場合、前述のCouchbase Liteプロジェクトを作成する同じ会社が同様のサービスに取り組んでいます Couchbase Lite for Android 。 iOSバージョンほど完全ではなく、達成する必要のある作業が残っています。

ただし、CouchDBで考慮すべき点がいくつかあります。

  1. 独自の競合解決を提供する必要があります。幸いなことに、競合が発生した場合、CouchDBは競合するバージョンとピック、および任意の、しかし決定論的な競合をメインバージョンとして保持します。したがって、初期バージョンの競合解決を遅らせることを検討できます。
  2. 複製メカニズムは、同期自体ではなく、データベースを複製するために作成されます。したがって、削除されたドキュメントが大量にある場合、サーバーからクライアントへの複製には時間がかかります。 「データベースローテーション」を使用してこれを回避する方法があります。これは基本的に古い削除を削除します。
  3. 複製の順序を制御することはできません。ただし、フィルターされた複製を使用して最初にいくつかのドキュメントを取得したり、オンデマンドでサーバーに直接アクセスしたりするなど、複製のパフォーマンスを向上させるための巧妙なソリューションを作成できます。
  4. レプリケーションは、iOSのバックグラウンドでは行われません。 iOS SDKを利用して、バックグラウンドレプリケーションのいくつかのケースを提供できます。

最後に、CouchDBを使用したくない場合は、少なくともそれをHTTP APIを使用して同期アルゴリズムを作成する方法の優れたリファレンスとして使用できます。私の提案は、CouchDBから始めて、さらにカスタムが必要な場合は、独自にロールすることを検討することです。

10
David V