A história é conhecida e vira e mexe aparece alguém perguntando sobre isso. Bom, você tem uma mesma aplicação rodando em lugares geograficamente distintos. Podem ser países diferentes, podem ser estados, cidades ou até mesmo bairros diferentes, o problema é praticamente o mesmo. Imagine uma cadeia de empresas, todas elas rodando o mesmo aplicativo.

Você pode chegar nesta situação quando era apenas uma matriz que abriu uma filial. O banco de dados ficava só na matriz e a filial acessa o banco de dados remotamente, via Internet, conexão via rádio, linha privativa, etc. O problema é que a conexão com a filial tinha a mania de cair e quando isso acontece é como se acabasse a luz. Se pensarmos numa empresa que utiliza apenas a conexão da Telefônica aqui em SP, dá para imaginar o desespero.

Então a solução ideal se chama replicação multimaster síncrona: você tem alguns bancos de dados, cada um em um local diferente. Cada atualização realizada numa das bases é automaticamente replicada para as demais e vice-versa. Qualquer base pode sofrer atualizações. Uma vez realizada, ela é visível instantaneamente em todas as bases. Se você der um rollback em uma transação, o rollback será realizado de forma idêntica em todos os nós. Ou seja, tem de garantir o ACID em todos os nós, como se estivesse em apenas um banco de dados. Existe um recurso no PostgreSQL que visa garantir este comportamento, ele se chama commit em duas fases e está disponível a partir da versão 8.1 do PostgreSQL. O commit em duas fases é muito importante por realmente garantir a consistência através de todos os nós. Ele não resolve problemas como o uso intensivo de SEQUÊNCIAS ou o a equivalência de um TIMESTAMP com precisão absoluta, mas resolve o problema de ter um commit ou rollback sincronizado em todos os nós. Deve-se entender que o Commit em duas fases é implemento como comandos SQL e não como uma aplicação. Portanto a sua aplicação tem de ser desenhada específicamente para utiliza-lo.

Há uma solução no universo PostgreSQL conhecida como PGCluster, que não utiliza o commit em duas fases mas faz a replicação multimaster assíncrona através de um serviço de balanceamento de carga e outro serviço de replicação. E vai além disso, se a comunicação com um dos nós cair, ele sincroniza o nó quando ele volta a se comunicar com os demais. Não é ótimo?

Sim, o PGCluster é uma ideia muito interessante, mas não como uma solução de banco de dados distribuído. Cada alteração no banco de dados dispara uma atualização em cada nós que precisa ser confirmada em um por um e depois da confirmação, liberada em todos eles. Isto significa que o que seria feito em X tempo em um único nó, será feito em  2XNL tempo onde N é o número de nós envolvidos na replicação e L é a latência da rede. Isto significa que se os nós não estiverem dispostos lado a lado numa rede local de alta velocidade, a perda de desempenho é absolutamente intolerável.

Mesmo que você utilize fibras ópticas de última geração para interligar seus servidores localizados em lugares distintos, você sofrerá com uma limitação: a velocidade da luz. Até que se prove ao contrário, nada viaja a uma velocidade superior a da luz, inclusive a informação. E nas idas e vindas do commit em duas fazes, a velocidade da luz começa a ser relevante. Ou seja, o PGCluster só é funcional como solução de alta disponibilidade, para servidores que ficam todos no mesmo CPD. Ainda assim há uma perda de performance considerável em cada atualização do banco de dados (nas leituras a distribuídas da carga propcia uma melhora de desempenho). Para encerrar o assunto, vale lembrar que o PGCluster é uma solução complexa de instalar (são no mínimo 3 nós + o balanceador de carga + o replicador), sua última versão foi lançada em 02/2008 e não é uma solução realmente bem aceita pelos desenvolvedores do PostgreSQL.

Sim o commit em duas fases pode ser utilizado com sucesso para bancos de dados distribuídos, mas para sincronizar apenas algumas operações e não a base inteira. Se você pesquisar bastante sobre o assunto, irá esbarrar em outras soluções:

Bom, mas então como resolvemos o problema das filiais??? Duas abordagens distintas:

As duas abordagens podem parecer um tanto radicais para você? Bom, eu diria que 90% dos grandes bancos utilizam exatamente estas abordagens:  possuem cerca de 3 ou 4 sites (digamos que em SP, DF e PE) cada uma respondendo por todas as transações da sua região. Há um investimento pesado para conectar todos os terminais no site da sua região. Se você precisar de informações de um site em outra região, a conexão é desviada para o site correto.

Estas são as duas formas óbvias de encarar o problema: centralizar tudo numa única base, ou dividir logo todos os dados em bases isoladas. Isto é tudo o que você pode fazer sem ter que mexer na lógica da aplicação. No entanto, se você está disposto a mexer na sua aplicação, particularmente na modelagem desta, então existe sim um meio termo. A primeira coisa a se fazer é dividir as tabelas em partes conforme as regras de negócio para a sua atualização:

  1. Tabelas que não são atualizadas ou que são atualizadas raramente: inclua aqui tabelas de parâmetros e coisas do tipo. Se você puder realizar as atualizações em apenas um local então você pode fazer com elas caiam no segundo caso:
  2. Tabelas que são atualizadas apenas em um nó como a matriz e são consultadas por todas as outras filiais;
  3. Tabelas onde cada filial é responsável pela atualização de apenas um punhado de registros, sendo que cada filial não pode alterar os registros da outra filial;
  4. Tabelas onde cada filial deve poder atualizar qualquer registro da tabela, independente de qual filial seja.

Como você pode perceber, não existe solução fácil. Mas, feliz são os desenvolvedores que criam suas aplicações já pensando neste tipo de solução. É claro que hoje se utiliza muito SOA, REST e outras tecnologias para trafegar informações entre aplicações. Outros se aventuram com o envio de TXT, ou XML para lá e para cá das mais diversas formas. Há ainda aqueles que criam uma teia de DBLinks para interligar as bases. Eu como DBA não sou especialista neste tipo de solução, mas acredito que elas sirvam para resolver outro tipo de problema. Um exemplo clássico seria a disponibilização de informações ou serviços de uma aplicação para outra aplicação diferente e não para a replicação de informações dentro de uma mesma aplicação. Trocar informações entre aplicações é muito diferente de replicar informações em bases distribuidas. A chave do problema sempre estará nas diferenças entre síncrono e assíncrono, e master/slave e multimaster.

Bom, eu acho que é só por enquanto. Se alguém conhecer outro tipo de solução que não seja baseada em nenhum dos casos aqui ou se tiver uma experiência que refute os argumentos que apresentei aqui, por favor deixe um comentário abaixo para trocarmos umas figurinhas, ok?

6 respostas

  1. Para o quarto caso, não é possível utilizar uma solução multi-master assíncrona?
    De qualquer forma, como o commit em duas fases poderia ser usado para realizar a replicação do quarto caso?

    Valeu.

  2. Fábio,

    Hoje estava navegando na web e resolvi dar uma passadinha pelo seu blog e parei para ler este teu post. Achei muito interessante o artigo que escreveste sobre a questão da replicação. Um excelente artigo. Parabéns.

    Abraços

  3. É a grande questão dos bancos de dados…
    Estou imaginando ( e tentando viabilizar) uma aplicação que envolve os notebooks da força de vendas, os bancos da filiais e uma base central.
    Os vendedores trabalham offline, cadastrando pedidos e clientes e consultando dados importantes de toda a base, seus dados off line tem que ter a atualização de toda a base…
    Cada filial (estou pensando em 27, no mínimo) teriam um servidor que pela manhã seu vendedores sincronizariam seus dados e a noite todas as filiais sincronizariam com a base central em duas etapas, sendo que pela manhã cada filial teriam sua base atualizada com a central para sincronizar com os vendedores, assim, os vendedores teriam sua base com um dia de atraso( é razoável…)
    O sistema seria uma boa base até que se tenha links bons a preços razoáveis e soluções de links móveis.
    O backup seria tranquilo, já que cada filial seria um…

    Como faço para iniciar a busca de informações e ferramentas para implementar este sistema?
    A segurança teria de ser muito forte, já que cada note tem toda a base…
    aguardo sugestões de por onde começar…

Deixe uma resposta