¿Cómo gestiona la sincronización bidireccional entre un servidor de base de datos 'principal' y muchos servidores 'secundarios', en particular la resolución de conflictos, suponiendo que una conexión no siempre esté disponible?
Por ejemplo, tengo una aplicación móvil que usa CoreData como la 'base de datos' en iOS y me gustaría permitir a los usuarios editar el contenido sin conexión a Internet. Al mismo tiempo, esta información está disponible en un sitio web al que se conectarán los dispositivos. ¿Qué hago si / cuando los datos en los dos servidores DB están en conflicto?
(Me refiero a CoreData como un servidor de base de datos, aunque sé que es algo ligeramente diferente).
¿Existen estrategias generales para tratar este tipo de problema? Estas son las opciones que se me ocurren:
1. Utilice siempre los datos del lado del cliente como de mayor prioridad
2. Lo mismo para el lado del servidor
3. Intente resolver conflictos marcando la marca de tiempo de edición de cada campo y tomando la última edición
Aunque estoy seguro de que la tercera opción abrirá espacio para una corrupción de datos devastadora.
Soy consciente de que el teorema de CAP se refiere a esto, pero solo quiero una consistencia eventual, por lo que no lo descarta por completo, ¿verdad?
Pregunta relacionada: Patrones de mejores prácticas para la sincronización de datos bidireccional . La segunda respuesta a esta pregunta dice que probablemente no se pueda hacer.
Respuestas:
La solución habitual para saber "qué cambio es correcto" es un reloj vectorial . Básicamente, realiza un seguimiento de los contadores para cada repositorio que contiene los datos y rechaza los cambios si la opinión de un cliente particular sobre el estado de todos los demás difiere de la del par al que se está conectando.
La gran pregunta que tienes que responder es cómo resolverás los guardados rechazados. Esto generalmente significa algún tipo de operación de fusión.
Tenga en cuenta que los relojes vectoriales no usan marcas de tiempo en tiempo real. Los problemas involucrados en la sincronización de relojes en tiempo real son al menos tan difíciles como la sincronización de datos.
fuente
Este es el problema de los generales bizantinos , que no tiene solución. Nunca puede garantizar la sincronización de los dos servidores si no puede garantizar que, en algún momento en el futuro , tendrá suficiente ancho de banda confiable para realizar la sincronización de una sola vez.
fuente
Supongo que no hay una forma estándar de hacerlo, cada sistema usa sus propias políticas para la resolución de conflictos.
Hice algunas simulaciones usando dos dispositivos, computadora y teléfono, y la hoja de cálculo de Google para verificar cómo Google Docs maneja los conflictos automáticamente. Aquí algunos casos:
Caso 1
Caso 2
Por lo tanto, al menos el servidor de Google Docs utiliza los últimos datos que recibió como prioridad más alta independientemente de cuándo se creó (marca de tiempo del cliente). También probé si se sincronizan en segundo plano, y aparentemente no lo hacen, por lo que el resultado de la resolución de conflictos es transparente para el usuario.
GIT, por otro lado, no maneja los conflictos automáticamente, sino que delega al último usuario que estaba tratando de alterar el repositorio de cómo debería hacerse la fusión.
Optaría por el enfoque de Google Docs si está bien solo sincronizar en primer plano, con el usuario visualizando los datos. De lo contrario, un usuario puede sorprenderse de que mientras su teléfono se conectaba automáticamente a un WiFi, un cambio no sincronizado en una reunión que luego reeditó en su PC se activó.
Optaría por el enfoque de marca de tiempo del cliente, anulando los conflictos con la última edición, si necesita sincronización en segundo plano, puedo confiar en la marca de tiempo del cliente y el costo de una fusión no deseada es menor que el costo de solicitar al usuario que elija la versión que desea mantener.
De lo contrario, optaría por el enfoque GIT, mostrando una ventana emergente en el siguiente cliente en primer plano pidiéndole al usuario que elija qué versión mantener o dando la oportunidad de revertir la fusión.
fuente