Sincronização de dados em aplicativos móveis - vários dispositivos, vários usuários


42

Estou pensando em criar meu primeiro aplicativo para dispositivos móveis. Um dos principais recursos do aplicativo é que vários dispositivos / usuários terão acesso aos mesmos dados - e todos eles terão direitos CRUD.

Eu acredito que a arquitetura deve envolver um servidor central onde todos os dados são armazenados. Os dispositivos usarão uma API para interagir com o servidor para executar suas operações de dados (por exemplo, adicionar um registro, editar um registro, excluir um registro).

Eu imagino um cenário em que sincronizar os dados se tornará um problema. Suponha que o aplicativo funcione quando não estiver conectado à Internet e, portanto, não possa se comunicar com este servidor central. Tão:

  1. O usuário A está offline e edita o registro # 100
  2. O usuário B está offline e edita o registro # 100
  3. O usuário C está offline e exclui o registro # 100
  4. O usuário C fica online (presumivelmente, o registro 100 deve ser excluído no servidor)
  5. O usuário A e B ficam on-line, mas os registros editados não existem mais

Todos os tipos de cenários semelhantes aos acima podem surgir.

Como isso geralmente é tratado? Eu pretendo usar o MySQL, mas estou me perguntando se não é apropriado para esse problema.

Respostas:


30

Atualmente, estou trabalhando em um aplicativo móvel / desktop / distribuído com exatamente os mesmos requisitos e problemas.

Antes de tudo, esses requisitos não são inerentes aos aplicativos móveis em si, mas a qualquer transação cliente-servidor desconectada / distribuída (programação paralela, multithreading, você entende). Como tal, é claro que são problemas típicos a serem abordados em aplicativos móveis.

Geralmente, tudo se resume a isso: você tem um registro de dados em potencial que é distribuído para n clientes, que podem editá-lo ao mesmo tempo. O que você precisa é

  1. um mecanismo de controle / travamento de versão adequado,
  2. um gerenciamento adequado de direitos / acesso,
  3. uma estratégia de sincronização / armazenamento em cache adequada

Para (1) você pode aplicar alguns padrões: Existem duas estratégias de bloqueio usadas com freqüência: Bloqueio Offline Otimista e Bloqueio Offline Pessimista . Algumas delas são aplicadas em diferentes "padrões" de controle de versão, como o MVCC ( MultiVersion Concurrency Control ), que usa um contador (uma espécie de "registro de data e hora" muito simples)) para cada registro de dados, que é atualizado sempre que o registro é alterado .

(2) e (3) são questões muito amplas, que precisam ser tratadas independentemente de (1). Alguns conselhos da minha experiência:

  • Use uma tecnologia cliente-servidor que abstraia a maioria dos problemas para você. Eu recomendo algumas tecnologias da Web, como o CouchDb , que lida com (1) via Optimistic Offline Locking + MVCC, (2) via Web API e (3) via cache Http muito bem.

  • Tente não inventar as coisas você mesmo se puder confiar em tecnologias e abordagens comprovadas. Acredito que qualquer hora gasta pesquisando e comparando tecnologias / padrões existentes é muito melhor do que tentando implementar seu próprio sistema (s).

  • Tente usar tecnologias homogêneas, se possível. Por "homogêneo", refiro-me às tecnologias que foram construídas com os mesmos princípios em mente, por exemplo, cenários de uso da Web 2.0. Um exemplo: usar um CouchDb e um cliente REST (API da Web) adequados com uma estratégia de cache local é uma escolha melhor do que usar o SQL para aplicativos móveis.

  • Eu desaconselho fortemente o uso do MySQL, porque é uma tecnologia que não foi explicitamente feita para esses cenários de uso. Funciona, mas você está muito melhor com um sistema de banco de dados que já adota o estilo de comunicação e concorrência na Web (como muitos bancos de dados NoSQL).

A propósito, escolhi o CouchDb com um cliente local personalizado que trabalha com as APIs do CouchDb, que funcionam e se adaptam perfeitamente. Eu mudei de usar o MSQL + (N) Hibernate e paguei um preço alto por não fazer a escolha certa (ou seja, não fazer pesquisas suficientes) em primeiro lugar.


O bloqueio otimista vs. pessimista foi a primeira coisa que me veio à cabeça ao ler a publicação do OP

10

Primeiro, você mencionou uma API e um banco de dados (MySQL). Eu recomendo que você use uma API e não tente se comunicar diretamente entre os bancos de dados. Essa última rota não será bem dimensionada.

Um bom ponto de partida que você deve considerar é usar o Apache CouchDB . É sem esquema, baseado em HTTP e JSON e possui um mecanismo de replicação muito bom. Nós o usamos para resolver um problema semelhante.

O mecanismo de replicação do CouchDB usa a mesma API HTTP usada por qualquer outro cliente. Portanto, em essência, ele fornece replicação por meio de uma API.

Para iOS, eu recomendo usar o projeto Couchbase Lite . Funciona muito bem para sincronizar dados. Para o Android, a mesma empresa que cria o projeto Couchbase Lite mencionado anteriormente está trabalhando em uma oferta semelhante - o Couchbase Lite para Android . Não é tão completo quanto a versão do iOS e ainda há algum trabalho a ser realizado.

No entanto, há algumas coisas a considerar no CouchDB.

  1. Você precisará fornecer sua própria resolução de conflito. Felizmente, se ocorrerem conflitos, o CouchDB mantém as versões e escolhas conflitantes e o conflito arbitrário, mas determinístico, como principal. Portanto, você pode considerar adiar a resolução de conflitos para sua versão inicial.
  2. O mecanismo de replicação é criado para replicar bancos de dados, não para sincronização em si. Portanto, se você tiver muitos documentos excluídos, sua replicação do servidor para o cliente levará mais e mais tempo. Existe uma maneira de evitar isso usando a "rotação do banco de dados". Isso remove essencialmente exclusões antigas.
  3. Você não pode controlar a ordem de replicação. No entanto, você pode criar soluções inteligentes para melhorar o desempenho da replicação, como usar a replicação filtrada para obter alguns documentos primeiro ou até mesmo acessar o servidor diretamente sob demanda.
  4. A replicação não ocorrerá em segundo plano no iOS. Você pode utilizar o SDK do iOS para fornecer alguns casos de replicação em segundo plano.

Por fim, se você não deseja usar o CouchDB, pode pelo menos usá-lo como uma boa referência para como criar um algoritmo de sincronização usando uma API HTTP. Minha sugestão seria começar com o CouchDB e, se você precisar de algo mais personalizado, considere criar o seu.


Meu plano para a API era implementar uma API RESTful usando CodeIgniter, que interagisse com qualquer solução de banco de dados necessária. Eu não estava pensando em usar um sistema de banco de dados que tivesse uma API integrada. Meu plano discorda da sua resposta?
ProgrammerNewbie

Além disso, agora estou olhando para o CouchDB. Criaria o aplicativo usando apenas o CouchDB? Ou ainda usaria algo como o MySQL em conjunto com o CouchDB? Por exemplo, o aplicativo ainda terá algumas necessidades básicas de um RDBMS. Modelo esse tipo de dados no MySQL e depois coloco os dados que requerem sincronização no CouchDB?
ProgrammerNewbie

Por favor, especifique sua "necessidade de um RDBMS". O que ele fornece que o CouchDb não? O CouchDb é um banco de dados NoSQL, portanto você não precisaria de um MySQL adicional. Além disso, o CouchDb pode oferecer um longo caminho sem a camada intermediária, pois você pode interceptar as chamadas da API usando JavaScript e criar sua saída com visualizações.
21713 Sebastian

@ ProgrammerNewbie, parece que seu plano geralmente é bom: faça uma API abstraindo do banco de dados. O CouchDB faz isso, mas você não é totalmente abstraído do fato de ser o CouchDB. Em relação à sua segunda pergunta, também não sei por que você precisa de um RDBMS. O CouchDB fornece visualizações de mapa / redução para consultas sobre dados, filtros, rastreamento de alterações e muito mais.
David Davi

@ Sebastian - eu não estou familiarizado com o NoSQL, então estou me perguntando se ainda preciso de um RDBMS para meus dados relacionais.
ProgrammerNewbie
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.