Sincronización de datos en aplicaciones móviles: múltiples dispositivos, múltiples usuarios
42
Estoy buscando construir mi primera aplicación móvil. Una de las características principales de la aplicación es que múltiples dispositivos / usuarios tendrán acceso a los mismos datos, y todos ellos tendrán derechos CRUD.
Creo que la arquitectura debería involucrar un servidor central donde se almacenan todos los datos. Los dispositivos utilizarán una API para interactuar con el servidor para realizar sus operaciones de datos (por ejemplo, agregar un registro, editar un registro, eliminar un registro).
Me imagino un escenario donde la sincronización de los datos se convertirá en un problema. Suponga que la aplicación debería funcionar cuando no está conectada a Internet y, por lo tanto, no puede comunicarse con este servidor central. Asi que:
El usuario A está desconectado y edita el registro # 100
El usuario B está desconectado y edita el registro # 100
El usuario C está desconectado y elimina el registro # 100
El usuario C se conecta (presumiblemente, el registro # 100 debería eliminarse en el servidor)
Los usuarios A y B se conectan, pero los registros que editaron ya no existen
Pueden surgir todo tipo de escenarios similares a los anteriores.
¿Cómo se maneja esto generalmente? Planeo usar MySQL, pero me pregunto si no es apropiado para tal problema.
Actualmente estoy trabajando en una aplicación móvil / de escritorio / distribuida con exactamente los mismos requisitos y problemas.
En primer lugar, estos requisitos no son inherentes a las aplicaciones móviles per se, sino a cualquier transacción cliente / servidor desconectada / distribuida (programación paralela, subprocesamiento múltiple, entiendes el punto). Como tales, son, por supuesto, problemas típicos para abordar en aplicaciones móviles.
En general, todo esto se reduce a que tiene un registro de datos potencial que se distribuye a n clientes, que pueden editarlo al mismo tiempo. Lo que necesitas es
un mecanismo de control / bloqueo de versión adecuado,
una adecuada gestión de derechos / acceso,
una estrategia adecuada de sincronización / almacenamiento en caché
Para (1) puede aplicar algunos patrones: hay dos estrategias de bloqueo de uso frecuente: bloqueo sin conexión optimista y bloqueo sin conexión pesimista . Algunos de estos vienen aplicados en diferentes "patrones" de control de versiones, como el Control de concurrencia de conversión múltiple (MVCC), que utiliza un contador (una especie de "marca de tiempo" muy simple) para cada registro de datos, que se actualiza cada vez que se cambia el registro .
(2) y (3) son cuestiones muy amplias en sí mismas, que deben abordarse independientemente de (1). Algunos consejos de mi experiencia:
Utilice una tecnología cliente-servidor que resuelva la mayoría de los problemas por usted. Recomiendo encarecidamente algunas tecnologías web como CouchDb , que maneja (1) a través de Optimistic Offline Locking + MVCC, (2) a través de Web API y (3) a través de caché Http muy bien.
Intente no inventar cosas usted mismo si puede confiar en tecnologías y enfoques probados. Creo que cualquier hora invertida en investigar y comparar tecnologías / patrones existentes es mucho mejor que intentar implementar sus propios sistemas.
Intente utilizar tecnologías homogéneas si es posible. Por "homogéneo" me refiero a las tecnologías que se han construido con los mismos principios en mente, por ejemplo, escenarios de uso de la web 2.0. Un ejemplo: usar un cliente CouchDb y REST adecuado (API web) con una estrategia de almacenamiento en caché local es una mejor opción que usar SQL para aplicaciones móviles.
Recomiendo encarecidamente el uso de MySQL porque es una tecnología que no se hizo explícitamente para tales escenarios de uso. Funciona, pero está mucho mejor con un sistema de base de datos que ya abarca el estilo de comunicación web y concurrencia (como muchas bases de datos NoSQL).
Por cierto, me he conformado con CouchDb con un cliente local personalizado que trabaja en contra de las API de CouchDb, que funciona y escala maravillosamente. Dejé de usar MSQL + (N) Hibernate y pagué un alto precio por no tomar la decisión correcta (es decir, no hacer suficiente investigación) en primer lugar.
+1 El bloqueo optimista frente al pesimista fue lo primero que se me vino a la cabeza al leer la publicación de OP
10
Primero, mencionó tanto una API como una base de datos (MySQL). Le recomiendo que use una API y no intente comunicarse directamente entre las bases de datos. Esa última ruta no escalará bien en absoluto.
Un buen punto de partida que debe considerar es usar Apache CouchDB . No tiene esquema, se basa en HTTP y JSON, y tiene un muy buen mecanismo de replicación. Lo usamos para resolver un problema similar.
El mecanismo de replicación de CouchDB usa la misma API HTTP que cualquier otro cliente. Entonces, en esencia, proporciona replicación sobre una API.
Para iOS, recomiendo usar el proyecto Couchbase Lite . Funciona muy bien para sincronizar datos. Para Android, la misma compañía que realiza el proyecto Couchbase Lite mencionado anteriormente está trabajando en una oferta similar: Couchbase Lite para Android . No es tan completo como la versión de iOS y le queda trabajo por hacer.
Sin embargo, hay algunas cosas a considerar con CouchDB.
Deberá proporcionar su propia resolución de conflictos. Afortunadamente, si se producen conflictos, CouchDB mantiene las versiones y las selecciones en conflicto y los conflictos arbitrarios, pero deterministas, como la versión principal. Por lo tanto, podría considerar retrasar la resolución de conflictos para su versión inicial.
El mecanismo de replicación está hecho para replicar bases de datos, no para la sincronización per se. Entonces, si tiene muchos documentos eliminados, su replicación del servidor al cliente llevará más tiempo. Hay una manera de evitar esto usando "rotación de base de datos". Esto esencialmente elimina las eliminaciones antiguas.
No puede controlar el orden de replicación. Sin embargo, puede hacer algunas soluciones inteligentes para mejorar el rendimiento de la replicación, como usar la replicación filtrada para obtener primero algunos documentos, o incluso acceder al servidor directamente a pedido.
La replicación no ocurrirá en segundo plano en iOS. Puede utilizar el SDK de iOS para proporcionar algunos casos de replicación en segundo plano.
Finalmente, si no desea usar CouchDB, al menos puede usarlo como una buena referencia de cómo podría hacer un algoritmo de sincronización usando una API HTTP. Mi sugerencia sería comenzar con CouchDB y luego, si necesita algo más personalizado, considerar rodar el suyo.
Mi plan para la API era implementar una API RESTful usando CodeIgniter, que interactuaría con cualquier solución de DB que fuera necesaria. No estaba pensando en usar un sistema de base de datos que tenía una API incorporada. ¿Mi plan no está de acuerdo con tu respuesta?
ProgrammerNewbie
Además, ahora estoy viendo CouchDB. ¿Construiría la aplicación usando solo CouchDB? ¿O seguiría usando algo como MySQL junto con CouchDB? Por ejemplo, la aplicación seguirá teniendo alguna necesidad básica de un RDBMS. ¿Modelo ese tipo de datos en MySQL y luego pongo los datos que requieren sincronización en CouchDB?
ProgrammerNewbie
Especifique su "necesidad de un RDBMS". ¿Qué proporciona que CouchDb no? CouchDb es una base de datos NoSQL, por lo que no necesitaría un MySQL adicional. Además, CouchDb puede ayudarlo mucho sin un nivel intermedio, ya que puede interceptar las llamadas a la API usando JavaScript y construir su salida con vistas.
Sebastian
@ProgrammerNewbie, parece que su plan es generalmente bueno: tener un resumen de API de la base de datos. CouchDB hace esto, pero no estás completamente abstraído del hecho de que es CouchDB. Con respecto a su segunda pregunta, tampoco sé por qué necesita un RDBMS. CouchDB proporciona vistas de mapa / reducción para proporcionar consultas sobre los datos, filtros, seguimiento de cambios y mucho más.
David V
@Sebastian: simplemente no estoy familiarizado con NoSQL, por lo que me pregunto si todavía necesito un RDBMS para mis datos relacionales.
Primero, mencionó tanto una API como una base de datos (MySQL). Le recomiendo que use una API y no intente comunicarse directamente entre las bases de datos. Esa última ruta no escalará bien en absoluto.
Un buen punto de partida que debe considerar es usar Apache CouchDB . No tiene esquema, se basa en HTTP y JSON, y tiene un muy buen mecanismo de replicación. Lo usamos para resolver un problema similar.
El mecanismo de replicación de CouchDB usa la misma API HTTP que cualquier otro cliente. Entonces, en esencia, proporciona replicación sobre una API.
Para iOS, recomiendo usar el proyecto Couchbase Lite . Funciona muy bien para sincronizar datos. Para Android, la misma compañía que realiza el proyecto Couchbase Lite mencionado anteriormente está trabajando en una oferta similar: Couchbase Lite para Android . No es tan completo como la versión de iOS y le queda trabajo por hacer.
Sin embargo, hay algunas cosas a considerar con CouchDB.
Finalmente, si no desea usar CouchDB, al menos puede usarlo como una buena referencia de cómo podría hacer un algoritmo de sincronización usando una API HTTP. Mi sugerencia sería comenzar con CouchDB y luego, si necesita algo más personalizado, considerar rodar el suyo.
fuente