ventajas transaccional sincronizar replicacion espejo enviar duplicar desventajas datos con sql database design-patterns client-server data-synchronization

sql - transaccional - Sincronización de bases de datos cliente-servidor



sincronizar sqlite con mysql (5)

Estoy buscando algunas estrategias generales para sincronizar datos en un servidor central con aplicaciones cliente que no siempre están en línea.

En mi caso particular, tengo una aplicación de teléfono Android con una base de datos sqlite y una aplicación web PHP con una base de datos MySQL.

Los usuarios podrán agregar y editar información en la aplicación del teléfono y en la aplicación web. Necesito asegurarme de que los cambios realizados en un lugar se reflejen en todas partes incluso cuando el teléfono no puede comunicarse inmediatamente con el servidor.

No me preocupa cómo transferir datos del teléfono al servidor o viceversa. Menciono mis tecnologías particulares solo porque no puedo usar, por ejemplo, las funciones de replicación disponibles para MySQL.

Sé que el problema de sincronización de datos entre el cliente y el servidor ha existido durante mucho, mucho tiempo y me gustaría obtener información (artículos, libros, consejos, etc.) sobre los patrones para manejar el problema. Me gustaría conocer las estrategias generales para lidiar con la sincronización para comparar fortalezas, debilidades y compensaciones.


Le recomendaría que tenga una columna de marca de tiempo en cada tabla y cada vez que inserte o actualice, actualice el valor de la marca de tiempo de cada fila afectada. Luego, itere sobre todas las tablas comprobando si la marca de tiempo es más nueva que la que tiene en la base de datos de destino. Si es más reciente, luego verifique si debe insertar o actualizar.

Observación 1: tenga en cuenta las eliminaciones físicas ya que las filas se eliminan de la base de datos fuente y debe hacer lo mismo en la base de datos del servidor. Puede solucionar esto evitando las eliminaciones físicas o registrando cada eliminación en una tabla con marcas de tiempo. Algo como esto: DeletedRows = (id, table_name, pk_column, pk_column_value, timestamp) Por lo tanto, debe leer todas las filas nuevas de la tabla DeletedRows y ejecutar una eliminación en el servidor utilizando table_name, pk_column y pk_column_value.

Observación 2: tenga en cuenta FK ya que podría fallar la inserción de datos en una tabla relacionada con otra tabla. Debe desactivar cada FK antes de la sincronización de datos.


Lo primero que tiene que decidir es una política general sobre qué lado se considera "autorizado" en caso de cambios conflictivos.

Es decir: supongamos que el Registro n. ° 125 se cambia en el servidor el 5 de enero a las 10 p.m. y se cambia el mismo registro en uno de los teléfonos (llamémoslo Cliente A) el 5 de enero a las 11 p.m. La última sincronización fue el 3 de enero. Luego, el usuario se vuelve a conectar, por ejemplo, el 8 de enero.

Identificar lo que se debe cambiar es "fácil" en el sentido de que tanto el cliente como el servidor conocen la fecha de la última sincronización, por lo que cualquier cosa creada o actualizada (vea más abajo más sobre esto) ya que la última sincronización debe reconciliarse.

Entonces, supongamos que el único registro modificado es el # 125. O bien decide que uno de los dos "gana" automáticamente y sobrescribe el otro, o necesita admitir una fase de conciliación donde un usuario puede decidir qué versión (servidor o cliente) es la correcta, sobrescribiendo a la otra.

Esta decisión es extremadamente importante y debe sopesar el "papel" de los clientes. Especialmente si existe un conflicto potencial no solo entre el cliente y el servidor, sino en el caso de que diferentes clientes puedan cambiar los mismos registros.

[Suponiendo que el # 125 puede ser modificado por un segundo cliente (Cliente B) existe la posibilidad de que el Cliente B, que aún no se ha sincronizado, proporcione otra versión del mismo registro, haciendo que la resolución de conflicto anterior sea discutible]

Con respecto al punto anterior " creado o actualizado " ... ¿cómo se puede identificar correctamente un registro si se ha originado en uno de los clientes (suponiendo que esto tenga sentido en su dominio problemático)? Supongamos que su aplicación administra una lista de contactos comerciales. Si el Cliente A dice que debe agregar un John Smith recién creado, y el servidor tiene un John Smith creado ayer por el Cliente D ... ¿crea dos registros porque no puede estar seguro de que no sean personas diferentes? ¿Le pedirás al usuario que concilie este conflicto también?

¿Los clientes tienen "propiedad" de un subconjunto de datos? Es decir, si el Cliente B está configurado para ser la "autoridad" en los datos para el Área n. ° 5, ¿puede el Cliente A modificar / crear registros para el Área n. ° 5 o no? (Esto facilitaría la resolución de conflictos, pero puede resultar inviable para su situación).

Para resumir, los principales problemas son:

  • Cómo definir "identidad" teniendo en cuenta que los clientes independientes pueden no haber accedido al servidor antes de crear un nuevo registro.
  • La situación anterior, no importa cuán sofisticada sea la solución, puede dar como resultado la duplicación de datos, por lo que debe prever cómo resolverla periódicamente y cómo informar a los clientes que lo que ellos consideraron como "Registro n. ° 675" se ha fusionado con / reemplazado por Registro # 543
  • Decida si los conflictos se resolverán por decreto (por ejemplo, "La versión del servidor siempre prevalece sobre la del cliente si la primera se ha actualizado desde la última sincronización") o mediante intervención manual.
  • En caso de fiduciario , especialmente si usted decide que el cliente tiene prioridad, también debe ocuparse de cómo tratar con otros clientes que aún no están sincronizados y que pueden tener algunos cambios más.
  • Los elementos anteriores no tienen en cuenta la granularidad de sus datos (para que las cosas sean más simples de describir). Baste decir que en lugar de razonar al nivel "Grabar", como en mi ejemplo, puede encontrar más apropiado para registrar el cambio en el nivel de campo, en su lugar. O para trabajar en un conjunto de registros (por ejemplo, registro de persona + registro de dirección + registro de contactos) a la vez tratando su agregado como una especie de "Meta Registro".

Bibliografía:

  • Más sobre esto, por supuesto, en Wikipedia .

  • Un algoritmo de sincronización simple por el autor de Vdirsyncer

  • Artículo de OBJC sobre sincronización de datos

  • SyncML®: Sincronización y administración de datos móviles (Libro sobre O''Reilly Safari)

  • Tipos de datos replicados sin conflicto

  • Replicación optimista YASUSHI SAITO (HP Laboratories) y MARC SHAPIRO (Microsoft Research Ltd.) - ACM Computing Surveys, vol. V, No. N, 3 2005.

  • Alexander Traud, Juergen Nagler-Ihlein, Frank Kargl y Michael Weber. 2008. Sincronización cíclica de datos mediante la reutilización de SyncML. En Actas de la Novena Conferencia Internacional sobre Gestión de Datos Móviles (MDM ''08). IEEE Computer Society, Washington, DC, EE. UU., 165-172. DOI = 10.1109 / MDM.2008.10 http://dx.doi.org/10.1109/MDM.2008.10

  • Lam, F., Lam, N. y Wong, R. 2002. Sincronización eficiente para datos XML móviles. En Actas de la Undécima Conferencia internacional sobre información y gestión del conocimiento (McLean, Virginia, EE. UU., Del 4 al 9 de noviembre de 2002). CIKM ''02. ACM, Nueva York, NY, 153-160. DOI = http://doi.acm.org/10.1145/584792.584820

  • Cunha, PR y Maibaum, TS 1981. Resource & Equil; tipo de datos abstractos + sincronización - Una metodología para la programación orientada a mensajes -. En Actas de la 5ª Conferencia internacional sobre ingeniería de software (San Diego, California, Estados Unidos, del 9 al 12 de marzo de 1981). Conferencia Internacional de Ingeniería de Software. IEEE Press, Piscataway, NJ, 263-272.

(Los últimos tres son de la biblioteca digital de ACM, no sé si eres miembro o si puedes obtenerlos a través de otros canales).

Desde el sitio Dr.Dobbs :

  • Creación de aplicaciones con SQL Server CE y SQL RDA por Bill Wagner 19 de mayo de 2004 (Mejores prácticas para diseñar una aplicación tanto para PC de escritorio como para PC móvil - Windows / .NET)

De arxiv.org:

  • Un tipo de datos JSON duplicados sin conflictos: el documento describe una implementación de JSON CRDT (tipos de datos replicados libres de conflictos, CRDT), son una familia de estructuras de datos que admiten modificaciones concurrentes y que garantizan la convergencia de dichas actualizaciones concurrentes).

Si alguien está lidiando con un problema de diseño similar y necesita sincronizar los cambios en varios dispositivos Android, recomiendo consultar Google Cloud Messaging for Android (GCM).

Estoy trabajando en una solución donde los cambios realizados en un cliente deben propagarse a otros clientes. Y acabo de implementar una implementación de prueba de concepto (servidor y cliente) y funciona como un encanto.

Básicamente, cada cliente envía cambios delta al servidor. Por ejemplo, el ID de recurso ABCD1234 ha cambiado del valor 100 a 99.

El servidor valida estos cambios delta contra su base de datos y aprueba el cambio (el cliente está sincronizado) y actualiza su base de datos o rechaza el cambio (el cliente no está sincronizado).

Si el cambio es aprobado por el servidor, el servidor notifica a otros clientes (excluyendo el que envió el cambio delta) a través de GCM y envía un mensaje de multidifusión con el mismo cambio delta. Los clientes procesan este mensaje y actualizan su base de datos.

Lo bueno es que estos cambios se propagan casi instantáneamente !!! si esos dispositivos están en línea. Y no necesito implementar ningún mecanismo de votación en esos clientes.

Tenga en cuenta que si un dispositivo está fuera de línea demasiado tiempo y hay más de 100 mensajes esperando en la cola de entrega de GCM, GCM descartará esos mensajes y enviará un mensaje especial cuando los dispositivos vuelvan a estar en línea. En ese caso, el cliente debe realizar una sincronización completa con el servidor.

Consulte también este tutorial para comenzar con la implementación del cliente CGM.


Sugiero que también le eches un vistazo a Symmetricds . es una biblioteca de réplica de SQLite disponible para sistemas android. puede usarlo para sincronizar su base de datos de cliente y servidor, también sugiero tener bases de datos separadas en el servidor para cada cliente. Intentar mantener los datos de todos los usuarios en una base de datos mysql no siempre es la mejor idea. Especialmente si los datos del usuario van a crecer rápidamente.


esto responde a los desarrolladores que están utilizando el marco Xamarin (ver https://.com/questions/40156342/sync-online-offline-data )

Una forma muy sencilla de lograr esto con el marco de trabajo de xamarin es utilizar la sincronización de datos sin conexión de Azure, ya que permite enviar y extraer datos del servidor a pedido. Las operaciones de lectura se realizan localmente y las operaciones de escritura se realizan bajo demanda; Si la conexión de red se rompe, las operaciones de escritura se ponen en cola hasta que se restaure la conexión y luego se ejecute.

La implementación es bastante simple:

1) crea una aplicación móvil en el portal azure (puedes probarla gratis aquí https://tryappservice.azure.com/ )

2) conecta tu cliente a la aplicación móvil. https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-xamarin-forms-get-started/

3) el código para configurar su repositorio local:

const string path = "localrepository.db"; //Create our azure mobile app client this.MobileService = new MobileServiceClient("the api address as setup on Mobile app services in azure"); //setup our local sqlite store and initialize a table var repository = new MobileServiceSQLiteStore(path); // initialize a Foo table store.DefineTable<Foo>(); // init repository synchronisation await this.MobileService.SyncContext.InitializeAsync(repository); var fooTable = this.MobileService.GetSyncTable<Foo>();

4) luego, presione y extraiga sus datos para asegurarse de tener los últimos cambios:

await this.MobileService.SyncContext.PushAsync(); await this.saleItemsTable.PullAsync("allFoos", fooTable.CreateQuery());

https://azure.microsoft.com/en-us/documentation/articles/app-service-mobile-xamarin-forms-get-started-offline-data/