Sincronizzazione dei dati nelle app mobili: più dispositivi, più utenti


42

Sto cercando di costruire la mia prima app mobile. Una delle caratteristiche principali dell'applicazione è che più dispositivi / utenti avranno accesso agli stessi dati e tutti avranno diritti CRUD.

Credo che l'architettura dovrebbe coinvolgere un server centrale in cui sono archiviati tutti i dati. I dispositivi utilizzeranno un'API per interagire con il server per eseguire le sue operazioni sui dati (ad es. Aggiunta di un record, modifica di un record, eliminazione di un record).

Immagino uno scenario in cui la sincronizzazione dei dati diventerà un problema. Supponiamo che l'applicazione dovrebbe funzionare quando non è connessa a Internet e quindi non può comunicare con questo server centrale. Così:

  1. L'utente A non è in linea e modifica il record # 100
  2. L'utente B non è in linea e modifica il record n. 100
  3. L'utente C non è in linea ed elimina il record n. 100
  4. L'utente C va online (presumibilmente, il record n. 100 dovrebbe essere eliminato sul server)
  5. Gli utenti A e B vanno online, ma i record che hanno modificato non esistono più

Possono venire fuori tutti i tipi di scenari simili a quelli precedenti.

Come viene generalmente gestito? Ho intenzione di utilizzare MySQL, ma mi chiedo se non è appropriato per un tale problema.

Risposte:


30

Attualmente sto lavorando su un'app mobile / desktop / distribuita con esattamente gli stessi requisiti e problemi.

Innanzitutto, questi requisiti non sono inerenti alle app mobili di per sé, ma a qualsiasi transazione client-server disconnessa / distribuita (programmazione parallela, multithreading, ottieni il punto). In quanto tali, ovviamente, sono problemi tipici da affrontare nelle app mobili.

In genere, tutto ciò si riduce a un potenziale record di dati che viene distribuito a n client, che possono modificarlo contemporaneamente. Quello di cui hai bisogno è

  1. un meccanismo di controllo / blocco della versione corretta,
  2. una corretta gestione dei diritti / accesso,
  3. una corretta strategia di sincronizzazione / memorizzazione nella cache

Per (1) è possibile applicare alcuni schemi: Esistono due strategie di blocco utilizzate frequentemente: Blocco offline ottimistico e Blocco offline pessimistico . Alcuni di questi vengono applicati in "modelli" di controllo versione diversi, come il controllo di concorrenza MultiVersion (MVCC), che utilizza un contatore (una sorta di "timestamp" molto semplice) per ogni record di dati, che viene aggiornato ogni volta che il record viene modificato .

(2) e (3) sono questioni molto ampie, che devono essere affrontate indipendentemente da (1). Alcuni consigli dalla mia esperienza:

  • Usa una tecnologia client-server che risolve la maggior parte dei problemi per te. Consiglio vivamente alcune tecnologie web come CouchDb , che gestisce (1) tramite Optimistic Offline Locking + MVCC, (2) tramite Web API e (3) tramite la cache Http molto bene.

  • Cerca di non inventare le cose da solo se puoi affidarti a tecnologie e approcci comprovati. Credo che ogni ora trascorsa a cercare e confrontare tecnologie / modelli esistenti sia molto meglio che cercare di implementare i propri sistemi.

  • Prova a usare tecnologie omogenee, se possibile. Per "omogeneo" intendo le tecnologie che sono state costruite con gli stessi principi in mente, ad esempio scenari di utilizzo del web 2.0. Un esempio: utilizzare un client CouchDb e REST (API Web) con una strategia di memorizzazione nella cache locale è una scelta migliore rispetto all'utilizzo di SQL per le app mobili.

  • Consiglio vivamente di non utilizzare MySQL perché è una tecnologia non esplicitamente creata per tali scenari di utilizzo. Funziona, ma stai molto meglio con un sistema di database che abbraccia già lo stile di comunicazione e concorrenza sul web (come molti database NoSQL).

A proposito, ho optato per CouchDb con un client locale personalizzato che lavora contro le API di CouchDb, che funziona e si ridimensiona magnificamente. Sono passato dall'uso di MSQL + (N) Hibernate e ho pagato un prezzo elevato per non aver fatto la scelta giusta (ovvero non aver fatto abbastanza ricerche) in primo luogo.


+1 Il blocco ottimistico vs. pessimistico è stata la prima cosa che mi è

10

Innanzitutto, hai menzionato sia un'API che un database (MySQL). Consiglio vivamente di utilizzare un'API e di non provare a comunicare direttamente tra i database. Quest'ultima via non si ridimensionerà affatto.

Un buon punto di partenza da considerare è l'utilizzo di Apache CouchDB . È senza schema, basato su HTTP e JSON, e ha un ottimo meccanismo di replica. Lo usiamo per risolvere un problema simile.

Il meccanismo di replica di CouchDB utilizza la stessa API HTTP utilizzata da qualsiasi altro client. Quindi, in sostanza, fornisce la replica su un'API.

Per iOS, consiglio di utilizzare il progetto Couchbase Lite . Funziona molto bene per la sincronizzazione dei dati. Per Android, la stessa azienda che realizza il suddetto progetto Couchbase Lite sta lavorando a un'offerta simile: Couchbase Lite per Android . Non è completo come la versione iOS e ha ancora del lavoro da compiere.

Tuttavia, ci sono alcune cose da considerare con CouchDB.

  1. Dovrai fornire la tua risoluzione dei conflitti. Fortunatamente, se si verificano conflitti, CouchDB mantiene le versioni e le scelte in conflitto e il conflitto arbitrario, ma deterministico, come versione principale. Quindi potresti considerare di ritardare la risoluzione dei conflitti per la tua versione iniziale.
  2. Il meccanismo di replica è creato per replicare i database, non la sincronizzazione in sé. Quindi, se hai molti documenti eliminati, la tua replica dal server al client richiederà sempre più tempo. C'è un modo per evitarlo usando la "rotazione del database". Questo essenzialmente rimuove le vecchie cancellazioni.
  3. Non puoi controllare l'ordine di replica. Tuttavia, è possibile creare alcune soluzioni intelligenti per migliorare le prestazioni della replica, ad esempio utilizzare la replica filtrata per ottenere prima alcuni documenti o persino accedere al server direttamente su richiesta.
  4. La replica non avverrà in background su iOS. È possibile utilizzare l'SDK di iOS per fornire alcuni casi di replica in background.

Infine, se non vuoi usare CouchDB, puoi almeno usarlo come un buon riferimento per come potresti fare un algoritmo di sincronizzazione usando un'API HTTP. Il mio suggerimento sarebbe di iniziare con CouchDB e quindi, se hai bisogno di qualcosa di più personalizzato, di prendere in considerazione l'idea di creare il tuo.


Il mio piano per l'API era di implementare un'API RESTful utilizzando CodeIgniter, che avrebbe interagito con qualunque soluzione DB fosse necessaria. Non pensavo di usare un sistema DB con API integrate. Il mio piano non è d'accordo con la tua risposta?
ProgrammerNewbie,

Inoltre, ora sto guardando CouchDB. Costruirò l'applicazione usando solo CouchDB? O userei ancora qualcosa come MySQL insieme a CouchDB? Ad esempio, l'applicazione avrà ancora alcune necessità di base per un RDBMS. Modello quel tipo di dati in MySQL e quindi inserisco i dati che richiedono la sincronizzazione in CouchDB?
ProgrammerNewbie,

Si prega di specificare la "necessità di un RDBMS". Cosa prevede che CouchDb non lo faccia? CouchDb è un database NoSQL, quindi non è necessario un MySQL aggiuntivo. Inoltre, CouchDb può farti fare molta strada senza un livello intermedio in quanto puoi intercettare le chiamate API usando JavaScript e costruire il tuo output con le viste.
Sebastian,

@ProgrammerNewbie, Sembra che il tuo piano sia generalmente buono: avere un'API in astratto dal database. CouchDB fa questo, ma non sei del tutto astratto dal fatto che è CouchDB. Per quanto riguarda la tua seconda domanda, non so nemmeno perché hai bisogno di un RDBMS. CouchDB fornisce mappe / riduci visualizzazioni per fornire query su dati, filtri, rilevamento delle modifiche e molto altro.
David V,

@Sebastian - Non ho familiarità con NoSQL, quindi mi chiedo se ho ancora bisogno di un RDBMS per i miei dati relazionali.
ProgrammerNewbie,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.