Resolução de conflitos para sincronização bidirecional

24

Como você gerencia a sincronização bidirecional entre um servidor de banco de dados 'principal' e muitos servidores 'secundários', em particular a resolução de conflitos, assumindo que uma conexão nem sempre esteja disponível?

Por exemplo, eu tenho um aplicativo móvel que usa CoreData como o 'banco de dados' no iOS e gostaria de permitir que os usuários editem o conteúdo sem conexão com a Internet. Ao mesmo tempo, essas informações estão disponíveis em um site ao qual os dispositivos se conectarão. O que faço se / quando os dados nos dois servidores de banco de dados estiverem em conflito?
(Refiro-me ao CoreData como um servidor de banco de dados, embora saiba que é algo um pouco diferente.)

Existem estratégias gerais para lidar com esse tipo de problema? Estas são as opções em que consigo pensar:
1. Sempre use os dados do cliente como de maior prioridade
2. O mesmo para o servidor
3. Tente resolver conflitos marcando o carimbo de data e hora de edição de cada campo e fazendo a edição mais recente

Embora eu tenha certeza de que a terceira opção abrirá espaço para uma corrupção de dados devastadora.

Estou ciente de que o teorema da CAP diz respeito a isso, mas eu só quero consistência eventual, para que não descarte completamente, certo?

Pergunta relacionada: Padrões de melhores práticas para sincronização de dados bidirecional . A segunda resposta a esta pergunta diz que provavelmente não pode ser feito.

K.Steff
fonte

Respostas:

14

A solução usual para saber "qual mudança está correta" é um relógio vetorial . Você essencialmente controla os contadores de cada repositório que contém os dados e rejeita as alterações se a visão de um cliente em particular do estado de todos os outros diferir da do ponto ao qual está se conectando.

A grande questão a ser respondida é como você resolverá os salvamentos rejeitados. Isso geralmente significa algum tipo de operação de mesclagem.

Observe que os relógios de vetor não usam carimbos de data / hora em tempo real. Os problemas envolvidos na sincronização de relógios em tempo real são pelo menos tão difíceis quanto a sincronização de dados.

parsifal
fonte
11
Bom, isso é o que eu estava procurando
K.Steff
10

Esse é o problema dos generais bizantinos , que é insolúvel. Você nunca pode garantir a sincronização dos dois servidores se não puder garantir que, em algum momento no futuro , você tenha largura de banda confiável suficiente para executar a sincronização de uma só vez.

DeadMG
fonte
Ok, mas como é que esses caras obter um efeito semelhante: desenvolvimento Syncpoint
K.Steff
3
Eles simplesmente assumem que você terá uma conexão confiável com largura de banda suficiente em algum momento no futuro.
DeadMG
1

Eu acho que não existe uma maneira padrão de fazer isso, cada sistema usa suas próprias políticas para a resolução de conflitos.

Fiz algumas simulações usando dois dispositivos, computador e telefone e a Planilha do Google para verificar como o Google Docs lida com conflitos automaticamente. Aqui estão alguns casos:

Caso 1

  1. Computador e telefone estão offline
  2. Computador editar célula com o valor 'computador' e depois do telefone editar célula com o valor 'telefone'
  3. Computador ficar online
  4. O telefone fica on-line e o computador e o telefone exibem 'telefone'.

Caso 2

  1. Computador e telefone estão offline
  2. Computador editar célula com o valor 'computador' e depois do telefone editar célula com o valor 'telefone'
  3. O telefone fica online
  4. O computador fica on-line e o computador e o telefone exibem 'computador'.

Portanto, pelo menos, o servidor do Google Docs usa os últimos dados recebidos como prioridade mais alta independentemente de quando foi criado (carimbo de data e hora do cliente). Também testei se eles fazem sincronização em segundo plano e, aparentemente, não fazem, portanto o resultado da resolução de conflitos é transparente para o usuário.

O GIT, por outro lado, não manipula conflitos automaticamente, mas delega para o último usuário que estava tentando alterar o repositório como a mesclagem deveria ser feita.

Eu usaria a abordagem do Google Docs se estiver tudo bem sincronizar apenas em primeiro plano, com o usuário visualizando os dados. Caso contrário, o usuário poderá se surpreender ao saber que, enquanto o telefone se conectava automaticamente a um WiFi, uma não sincronização muda para uma reunião que ele depois de reeditar no PC foi ao ar.

Eu usaria a abordagem de carimbo de data / hora do cliente, substituindo os conflitos pela última edição, se você precisar de sincronização em segundo plano, pode confiar no carimbo de data / hora do cliente e o custo de uma mesclagem indesejável é menor do que o custo de solicitar ao usuário que escolha a versão que ele deseja manter.

Eu usaria a abordagem GIT de outra forma, mostrando um pop-up no próximo cliente em primeiro plano, pedindo ao usuário que escolhesse qual versão manter ou dando a chance de reverter a mesclagem.

Allan Veloso
fonte
11
Concordo que uma abordagem caso a caso é a maneira apropriada de seguir aqui. A maneira "melhor" (abordagem git) nem sempre é aplicável, pois os usuários podem não querer revisar / mesclar as alterações
K.Steff