Synchronizacja danych w aplikacjach mobilnych - wiele urządzeń, wielu użytkowników

42

Chcę zbudować swoją pierwszą aplikację mobilną. Jedną z podstawowych funkcji aplikacji jest to, że wiele urządzeń / użytkowników będzie miało dostęp do tych samych danych - a wszystkie z nich będą miały prawa CRUD.

Uważam, że architektura powinna obejmować centralny serwer, na którym przechowywane są wszystkie dane. Urządzenia będą używać interfejsu API do interakcji z serwerem w celu wykonywania operacji na danych (np. Dodawania rekordu, edytowania rekordu, usuwania rekordu).

Wyobrażam sobie scenariusz, w którym synchronizacja danych stanie się problemem. Załóżmy, że aplikacja powinna działać, gdy nie jest połączona z Internetem, a zatem nie może komunikować się z tym serwerem centralnym. Więc:

  1. Użytkownik A jest offline i edytuje rekord 100
  2. Użytkownik B jest offline i edytuje rekord 100
  3. Użytkownik C jest offline i usuwa rekord nr 100
  4. Użytkownik C przechodzi do trybu online (przypuszczalnie rekord 100 powinien zostać usunięty z serwera)
  5. Użytkownicy A i B są online, ale edytowane przez nich rekordy już nie istnieją

Mogą pojawić się różnego rodzaju scenariusze podobne do powyższych.

Jak to się ogólnie zajmuje? Planuję używać MySQL, ale zastanawiam się, czy nie jest to odpowiednie dla takiego problemu.

ProgrammerNewbie
źródło

Odpowiedzi:

30

Obecnie pracuję nad aplikacją mobilną / stacjonarną / rozproszoną z dokładnie tymi samymi wymaganiami i problemami.

Po pierwsze, wymagania te nie są nieodłącznie związane z aplikacjami mobilnymi per se, ale z wszelkimi rozłączonymi / rozproszonymi transakcjami klient-serwer (programowanie równoległe, wielowątkowość, masz rację). Jako takie są oczywiście typowymi problemami do rozwiązania w aplikacjach mobilnych.

Ogólnie rzecz biorąc, sprowadza się to do tego, że masz potencjalny rekord danych, który jest dystrybuowany do n klientów, którzy mogą go edytować w tym samym czasie. Potrzebujesz tego

  1. odpowiedni mechanizm kontroli / blokowania wersji,
  2. właściwe zarządzanie prawami / dostępem,
  3. odpowiednia strategia synchronizacji / buforowania

Dla (1) możesz zastosować pewne wzorce: Istnieją dwie często stosowane strategie blokowania: optymistyczne blokowanie offline i pesymistyczne blokowanie offline . Niektóre z nich są stosowane w różnych „wzorach” kontroli wersji, takich jak MultiVersion Concurrency Control (MVCC), która wykorzystuje licznik (rodzaj bardzo prostego „znacznika czasu”) dla każdego rekordu danych, który jest aktualizowany po każdej zmianie rekordu .

(2) i (3) same w sobie są bardzo szerokimi zagadnieniami, którymi należy się zająć niezależnie od (1). Kilka rad z mojego doświadczenia:

  • Skorzystaj z technologii klient-serwer, która pozbywa się większości problemów. Bardzo polecam niektóre technologie sieciowe, takie jak CouchDb , który obsługuje (1) przez Optymistyczne Blokowanie Offline + MVCC, (2) przez Web API i (3) bardzo dobrze buforuje HTTP.

  • Staraj się nie wymyślać rzeczy samodzielnie, jeśli możesz polegać na sprawdzonych technologiach i podejściach. Uważam, że każda godzina spędzona na badaniu i porównywaniu istniejących technologii / wzorców jest znacznie lepsza niż próba wdrożenia własnego systemu (systemów).

  • W miarę możliwości staraj się stosować homogeniczne technologie. Przez „jednorodny” rozumiem technologie, które zostały zbudowane z myślą o tych samych zasadach, np. Scenariusze użycia Web 2.0. Przykład: użycie odpowiedniego CouchDb i klienta REST (Web API) z lokalną strategią buforowania jest lepszym wyborem niż użycie SQL dla aplikacji mobilnych.

  • Zdecydowanie odradzam korzystanie z MySQL, ponieważ jest to technologia, która nie została specjalnie stworzona dla takich scenariuszy użycia. Działa, ale znacznie lepiej jest z systemem baz danych, który już obejmuje styl komunikacji internetowej i styl współbieżności (taki jak wiele baz danych NoSQL).

Nawiasem mówiąc, zdecydowałem się na CouchDb z niestandardowym lokalnym klientem działającym przeciwko interfejsom API CouchDb, który działa i skaluje się pięknie. Zrezygnowałem z używania MSQL + (N) Hibernacja i zapłaciłem wysoką cenę za to, że nie dokonałem właściwego wyboru (co oznacza, że ​​nie przeprowadziłem wystarczającej liczby badań).

Sebastian
źródło
+1 Optymistyczne kontra pesymistyczne blokowanie było pierwszą rzeczą, która pojawiła się w mojej głowie, czytając post OP
10

Po pierwsze, wspomniałeś zarówno API, jak i bazę danych (MySQL). Bardzo polecam korzystanie z interfejsu API i nie próbować komunikować się bezpośrednio między bazami danych. Ta ostatnia trasa w ogóle nie będzie dobrze skalowana.

Jednym dobrym punktem wyjścia, który należy wziąć pod uwagę, jest użycie Apache CouchDB . Jest bez schematu, oparty na HTTP i JSON, i ma bardzo dobry mechanizm replikacji. Używamy go do rozwiązania podobnego problemu.

Mechanizm replikacji CouchDB korzysta z tego samego interfejsu API HTTP, z którego korzysta każdy inny klient. Zasadniczo zapewnia replikację przez interfejs API.

W przypadku systemu iOS polecam korzystanie z projektu Couchbase Lite . Działa bardzo dobrze do synchronizacji danych. W przypadku Androida ta sama firma, która wykonuje wspomniany projekt Couchbase Lite, pracuje nad podobną ofertą - Couchbase Lite dla Androida . Nie jest tak kompletny jak wersja na iOS i pozostało trochę do zrobienia.

Jest jednak kilka rzeczy do rozważenia w przypadku CouchDB.

  1. Musisz podać własne rozwiązanie konfliktu. Na szczęście, jeśli wystąpią konflikty, CouchDB zachowuje sprzeczne wersje i typy oraz arbitralny, ale deterministyczny konflikt jako główną wersję. Możesz więc rozważyć opóźnienie rozwiązania konfliktu w pierwszej wersji.
  2. Mechanizm replikacji służy do replikacji baz danych, a nie do samej synchronizacji. Jeśli więc masz dużo usuniętych dokumentów, replikacja z serwera do klienta będzie trwała coraz dłużej. Jest sposób, aby tego uniknąć, używając „rotacji bazy danych”. To zasadniczo usuwa stare usunięcia.
  3. Nie można kontrolować kolejności replikacji. Można jednak wprowadzić sprytne rozwiązania w celu poprawy wydajności replikacji, takie jak użycie replikacji filtrowanej do uzyskania najpierw niektórych dokumentów lub nawet bezpośredni dostęp do serwera na żądanie.
  4. Replikacja nie będzie się odbywać w tle na iOS. Możesz użyć zestawu iOS SDK, aby zapewnić niektóre przypadki replikacji w tle.

Wreszcie, jeśli nie chcesz używać CouchDB, możesz przynajmniej użyć go jako dobrego źródła informacji o tym, jak stworzyć algorytm synchronizujący za pomocą interfejsu API HTTP. Moją propozycją byłoby zacząć od CouchDB, a następnie, jeśli potrzebujesz czegoś bardziej niestandardowego, zastanów się nad stworzeniem własnego.

David V.
źródło
Mój plan dotyczący interfejsu API polegał na wdrożeniu interfejsu API RESTful przy użyciu CodeIgniter, który współdziałałby z dowolnym niezbędnym rozwiązaniem DB. Nie myślałem o użyciu systemu DB z wbudowanym API. Czy mój plan nie zgadza się z twoją odpowiedzią?
ProgrammerNewbie
Teraz patrzę teraz na CouchDB. Czy zbudowałbym aplikację przy użyciu tylko CouchDB? A może nadal używałbym czegoś takiego jak MySQL w połączeniu z CouchDB? Na przykład aplikacja nadal będzie potrzebować podstawowej obsługi RDBMS. Czy modeluję tego rodzaju dane w MySQL, a następnie umieszczam dane wymagające synchronizacji w CouchDB?
ProgrammerNewbie
Podaj swoją „potrzebę RDBMS”. Co to zapewnia, że ​​nie CouchDb? CouchDb to baza danych NoSQL, więc nie potrzebujesz dodatkowej MySQL. Co więcej, CouchDb może zapewnić ci długą drogę bez pośredniej warstwy, ponieważ możesz przechwytywać wywołania API za pomocą JavaScript i budować wyniki za pomocą widoków.
Sebastian
@ProgrammerNewbie, Wygląda na to, że Twój plan jest ogólnie dobry: mieć API wyodrębnione z bazy danych. CouchDB w pewnym sensie to robi, ale nie jesteś całkowicie abstrakcyjny z faktu, że jest to CouchDB. Jeśli chodzi o twoje drugie pytanie, nie wiem też, dlaczego potrzebujesz RDBMS. CouchDB zapewnia widoki mapy / zmniejszania w celu dostarczania zapytań o dane, filtrów, śledzenia zmian i wielu innych.
David V
@Sebastian - po prostu nie znam NoSQL, więc zastanawiam się, czy nadal potrzebuję RDBMS dla moich danych relacyjnych.
ProgrammerNewbie