2010-01-19 11 views
40

En el mundo de hoy, donde muchas computadoras, dispositivos móviles o servicios web comparten datos o actúan como centros, la sincronización se vuelve más importante. Como todos sabemos, las soluciones que sincronizan no son las más cómodas y lo mejor es no sincronizarlas en absoluto.¿Cuál es el enfoque más inteligente y fácil para sincronizar datos entre múltiples entidades?

Todavía tengo curiosidad de cómo implementaría una solución de sincronización para sincronizar entre varias entidades. Ya hay muchos enfoques diferentes, como comparar un campo de fecha modificada o un hash y usar los datos más recientes o dejar que el usuario elija lo que quiere usar en caso de conflicto. Otro enfoque es tratar de fusionar automáticamente los datos en conflicto (que en mi opinión no es tan inteligente, porque una máquina no puede adivinar a qué se refería el usuario).

De todos modos, aquí hay un par de preguntas relacionadas con la sincronización que hay que responder antes de comenzar a implementar la sincronización:

  • ¿Qué son los datos más recientes? ¿Cómo quiero representarlo?
  • ¿Qué debo hacer en caso de conflicto? ¿Unir? ¿Indico y le pregunto al usuario qué hacer?
  • ¿Qué hago cuando me encuentro en un estado incoherente (por ejemplo, una desconexión debido a una conexión de red móvil flakey)?
  • ¿Qué debo hacer cuando no quiero entrar en un estado incoherente?
  • ¿Cómo puedo reanudar una sincronización actual que se interrumpió?
  • ¿Cómo manejo el almacenamiento de datos (por ejemplo, la base de datos MySQL en un servicio web, Core Data en un iPhone y cómo fusionar/sincronizar los datos sin un montón de código de pegamento)?
  • ¿Cómo debo manejar las ediciones del usuario que ocurren durante la sincronización (que se ejecuta en segundo plano, por lo que la IU no está bloqueada)?
  • Cómo y en qué dirección propago los cambios (por ejemplo, un usuario crea una entrada "Foo" en su computadora y no se sincroniza; luego está en movimiento y crea otra entrada "Foo"; qué sucede cuando intenta sincronizar ambos dispositivos)? ¿El usuario tendrá dos entradas "Foo" con diferentes ID únicos? ¿El usuario tendrá solo una entrada, pero cuál?
  • ¿Cómo debo manejar la sincronización cuando tengo datos jerárquicos? ¿De arriba hacia abajo? ¿De abajo hacia arriba? ¿Trato cada entrada de forma atómica o solo miro un supernodo? ¿Qué tan grande es la disyuntiva entre simplificar demasiado las cosas e invertir demasiado tiempo en la implementación?
  • ...

Hay muchas otras preguntas y espero que yo pudiera inspirar suficiente. La sincronización es un problema bastante general. Una vez que se encuentra un enfoque bueno y versátil de sincronización, debería ser más fácil aplicarlo a una aplicación concreta, en lugar de comenzar a pensar desde cero. Me doy cuenta de que ya hay muchas aplicaciones que intentan resolver (o resolver con éxito) la sincronización, pero ya son bastante específicas y no dan suficientes respuestas para sincronizar los enfoques en general.

Respuesta

44

Donde trabajo, hemos desarrollado una versión "offline" de nuestra aplicación principal (web) para que los usuarios puedan trabajar en sus computadoras portátiles en lugares donde no tienen acceso a Internet (no estoy seguro de cuántos de estos lugares realmente existen en estos días, pero me han dicho que sí;)). Cuando el usuario vuelve al sitio principal, necesita sincronizar los datos que ingresaron sin conexión con nuestra aplicación principal.

Por lo tanto, para responder a sus preguntas:

  • ¿Qué son los datos más recientes? ¿Cómo quiero representarlo?

Tenemos una columna LAST_UPDATED_DATE en cada mesa. El servidor realiza un seguimiento de cuándo ocurren las sincronizaciones, de modo que cuando la aplicación fuera de línea solicita una sincronización, el servidor dice "hey, solo dame los datos modificados desde esta fecha".

  • ¿Qué hago en caso de un conflicto? ¿Unir? ¿Pregunto y pregunto al usuario qué hacer?

En nuestro caso, la aplicación en línea sólo es capaz de actualizar un subconjunto relativamente pequeño de todos los datos. Como cada registro está sincronizado, verificamos si es uno de estos casos, y si es así, comparamos el LAST_UPDATED_DATE para el registro tanto en línea como fuera de línea. Si las fechas son diferentes, también verificamos los valores (porque no hay conflicto si ambos se actualizan con el mismo valor). Si hay un conflicto, registramos la diferencia, establecemos una bandera para indicar que hay al menos un conflicto y seguimos comprobando el resto de los detalles. Una vez que finaliza el proceso, si se establece el indicador "isConflict", el usuario puede ir a una página especial que muestra las diferencias y decide qué datos son la versión "correcta". Esta versión se guarda en el host y se restablece el indicador "isConflict".

  • ¿Qué tengo que hacer cuando no quiero entrar en un estado incoherente ?
  • ¿Cómo puedo reanudar una sincronización actual que se interrumpió?

Bueno, nosotros tratamos de evitar entrar en un estado incoherente en el primer lugar.Si una sincronización se interrumpe por algún motivo, la última_sincronización_fecha no se actualiza, por lo que la próxima vez que se inicie una sincronización comenzará desde la misma fecha que la fecha de inicio de la sincronización previa (interupptada).

  • ¿Cómo manejo de almacenamiento de datos (por ejemplo, la base de datos MySQL en un servicio web, Core de datos en un iPhone, y cómo puedo fusión/sincronizar los datos sin una gran cantidad de código de unión)?

Utilizamos bases de datos estándar en ambas aplicaciones, y objetos de Java en el medio. Los objetos se serializan a XML (y gzip para acelerar la transferencia) para el proceso de sincronización real, luego se descomprimen/deserializan en cada extremo.

  • ¿Cómo debo manejar ediciones del usuario que suceda durante la sincronización (que se ejecuta en segundo plano, por lo que el interfaz de usuario no está bloqueado)?

Estos cambios se llevarían a cabo después de la fecha de inicio de la sincronización, por lo que no sería recogido por el otro lado hasta la siguiente sincronización.

  • ¿Cómo y en qué dirección puedo propagar los cambios (por ejemplo, un usuario crea una entrada de “Foo” en su ordenador y no se sincroniza, entonces está en el ir y crea otro “Foo” entrada; ¿qué ocurre cuando intenta sincronizar ambos dispositivos )? ¿El usuario tendrá dos entradas "Foo" con diferentes ID únicos? ¿El usuario tiene una sola entrada, pero cuál?

Eso depende de usted para decidir cómo desea manejar este particular Foo ... es decir, dependiendo de lo que la clave primaria de Foo es y cómo determinar si una Foo es igual a otro.

  • ¿Cómo debo manejar sincronización cuando tengo datos jerárquicos? ¿De arriba hacia abajo? De abajo hacia arriba? ¿Trato cada entrada de forma atómica o solo miro un supernodo ?

La sincronización es atómica, por lo que si un registro falla, entonces todo el proceso está marcada como incompleta, similar a una subversión confirmar la transacción.

  • ¿Qué tan grande es el compromiso entre simplificar las cosas y la inversión demasiado tiempo en la puesta en práctica?

No estoy seguro exactamente lo que quieres decir, pero yo diría que todo depende de su situación y el tipo/cantidad de datos que desea sincronizar. Puede llevar mucho tiempo diseñar e implementar el proceso, pero es posible.

Espero que te ayude o al menos que te dé algunas ideas! :)

+0

por favor ayuda a introducir algunos algoritmos de sincronización, gracias! – Charles0429

+0

Sí, comparta cualquier algoritmo para que sea más fácil. –

+0

Creo que el No1 debe estar en reversa, el cliente debe determinar los candidatos para la sincronización, no el servidor. por ejemplo, en mi dispositivo LAST_UPDATED_DATE es a las 2:00 p.m., luego hice cambios a las 2:10 p.m. mientras estaba desconectado, pero un colega mío actualizó el mismo registro a las 2:30 p.m. y se guardó, LAST_UPDATED_DATE en el servidor es ahora las 2:30 p.m., perdería los cambios que hice a las 2:10 pm si el servidor debe determinar los candidatos de sincronización. –

4

Probablemente "No es una cuestión real", aquí no es una respuesta real:

Creo que los sistemas de control de versiones distribuido (como Mercurial o Git) he descubierto una gran parte de esto. Sin embargo, requieren que las personas acepten que puede haber más de una versión "más reciente", y que a veces las actualizaciones conflictivas necesitan una resolución manual para resolverlas. Además, si no está interesado en mantener todo el historial de cambios, hay un poco de sobrecarga en estos sistemas (pero, por supuesto, la historia reciente es necesaria para encontrar ancestros comunes para determinar cómo se relacionan las dos versiones).

Pero estoy de acuerdo con que en un mundo donde todos tienen datos distribuidos en múltiples dispositivos y servicios, la necesidad de realizar un seguimiento y distribuir automáticamente las actualizaciones será tan urgente que los formatos de archivo comunes utilizados por las aplicaciones incluirán metadatos para facilitar algún tipo de comportamiento de fusión inteligente. Pero ese comportamiento probablemente tendrá que ocurrir en el nivel de la aplicación, porque no hay una manera genérica de resolver las actualizaciones conflictivas.

Mientras tanto, el enfoque iTunes-iPod es el más fácil: solo tiene una biblioteca maestra y cada dispositivo extrae desde allí. Obviamente, single-master-sync no es muy satisfactorio en todos los escenarios (especialmente cuando se trata de más de un usuario), pero aún así, agradecería que más aplicaciones ofrecieran la opción de funcionar así (lo que más me molesta: tengo tres Mac , con tres instalaciones de iPhoto. Si se sincronizaran automáticamente desde un maestro dedicado, al igual que las fotos sincronizadas con mi iPod, eso sería una mejora).

0

Gracias por la respuesta detallada GaZ. Tengo un par de preguntas de seguimiento:

Si utiliza marcas de tiempo, ¿cómo maneja las configuraciones de tiempo incorrectas (pequeñas diferencias, por ejemplo 1-5 segundos)? ¿Con qué frecuencia aparecen? ¿No es mejor un control de versiones (como SVN) para manejar diferentes cambios de datos?

Entiendo que solo obtiene datos entre dos marcas de hora, la last_synchronisation_date (por cliente) y ahora?

¿Qué haces cuando un usuario no resuelve los conflictos? ¿No sincroniza los datos que están marcados con el indicador isConflict o agrega otro conflicto, por lo que el usuario puede elegir entre más de dos versiones de una entidad cuando decide resolver todos los conflictos? ¿O no sincronizas en absoluto si hay algunos datos marcados como conflictivos?

+0

Las fechas utilizadas están todas en el servidor, por lo que siempre que el reloj no cambie en el servidor, no habrá diferencias. ¿No está seguro de lo que quiere decir con el control de versiones, lo siento? Si un usuario no resuelve un conflicto, los datos para esa entidad particular no se sincronizarán nuevamente. Sin embargo, otras entidades aún pueden sincronizar. – GaZ

+0

Con el versionado me refiero a un valor entero como propiedad para cada objeto. Dos valores incrementales, uno para la versión actual y otro para la última versión sincronizada, se comparan durante una sincronización y, en función de las diferencias en los números de versión, se propagan los cambios o se marcan los datos como conflictivos. –

Cuestiones relacionadas