Temos uma configuração de baunilha mestre e escravo do MySQL que reside em diferentes datacenters e outro escravo no mesmo datacenter que o mestre.
A largura de banda entre o datacenter é bastante alta (nos benchmarks de rede que fizemos, podemos atingir 15 MB / segundo), mas a latência existe, é de cerca de 28 ms. Não é alto de forma alguma, mas é muito mais alto que a latência de menos de um segundo no mesmo data center.
Ocasionalmente, experimentamos atrasos sérios (2000 segundos e mais) com o escravo de remoção, enquanto o escravo local permanece atualizado. Ao observar o escravo remoto atrasado, o encadeamento SQL geralmente gasta o tempo aguardando o encadeamento de E / S para atualizar o log de retransmissão. O mestre mostra "aguardando net" ou algo do tipo ao mesmo tempo.
Isso significa que é de rede, mas ainda temos largura de banda gratuita no momento em que isso acontece.
Minha pergunta é : a latência entre os datacenters afeta o desempenho da replicação? O encadeamento io do escravo apenas transmite os eventos até que o mestre pare de enviá-los, ou está agrupando o mestre de alguma forma entre os eventos?
fonte
Respostas:
A resposta direta à sua pergunta é Sim, mas depende da versão do MySQL que você está executando. Antes do MySQL 5.5, a replicação operaria da seguinte maneira:
No MySQL 5.5, usando Replicação Semissíncrona , agora a replicação operaria da seguinte maneira:
Esse novo paradigma permitirá que um escravo seja mais sincronizado com seu mestre.
Não obstante, a latência dentro da rede pode dificultar a replicação semisync do MySQL até o ponto em que reverte para a replicação assíncrona no estilo antigo. Por quê ? Se ocorrer um tempo limite sem que nenhum escravo tenha reconhecido a transação, o mestre reverterá para replicação assíncrona. Quando pelo menos um escravo semi-síncrono alcança, o mestre retorna à replicação semissíncrona.
UPDATE 2011-08-08 14:22 EDT
A configuração da replicação semi-síncrona do MySQL 5.5 é direta
Etapa 1) Adicione essas quatro (4) linhas ao /etc/my.cnf
Etapa 2) Reinicie o MySQL
Etapa 3) Execute estes comandos no cliente MySQL
Etapa 4) Remova o comentário das três opções rpm_semi_sync após a opção plugin-dir
Etapa 5) Reinicie o MySQL
Tudo feito !!! Agora basta configurar o MySQL Replication como de costume.
fonte
Gosto muito de como Rolando descreveu a sequência de operações que uma replicação executa. No entanto, acho que seria mais claro se adicionarmos outro componente - cliente.
Com o cliente, a sequência de operações para replicação assíncrona pode ser a seguinte:
O cliente envia ao mestre a consulta SQL (por exemplo, inserir) usando transações
O mestre executa a transação. Em caso de sucesso, o registro é armazenado no disco, mas a transação ainda não foi confirmada.
O mestre registra o evento de inserção no log binário mestre Se o mestre não puder armazená-lo no log binário, a transação será revertida.
O cliente recebe resposta do mestre (êxito ou reversão).
Em caso de êxito da transação, o encadeamento de despejo no mestre lê o evento do log binário e o envia para o encadeamento de E / S escravo.
O encadeamento de E / S escrava recebe o evento e o grava no final do arquivo de log de retransmissão.
Depois que o evento entra no log de retransmissão, o encadeamento SQL do escravo executa
o evento para aplicar as alterações no banco de dados no escravo.
Nesse cenário, o mestre não se importa com o escravo e o cliente sabe apenas que algo está errado no escravo executando manualmente o comando "SHOW SLAVE STATUS".
No caso de uma replicação semi-síncrona, a sequência de operações pode ser a seguinte:
O cliente envia ao mestre a consulta SQL (por exemplo, inserção) usando transações.
O mestre executa a transação. Em caso de sucesso, o registro é armazenado no disco, mas a transação não é confirmada.
O mestre registra o evento de inserção no log binário mestre Se o mestre não puder armazená-lo no log binário, a transação será revertida e o cliente receberá a resposta apenas no caso de reversão.
Devido ao sucesso da transação no mestre, o encadeamento de despejo no mestre lê o evento do log binário e o envia para o encadeamento de E / S escravo.
O encadeamento de E / S escrava recebe o evento e o grava no final do arquivo de log de retransmissão.
Escravo Reconhece o mestre da gravação do evento no arquivo de log de retransmissão.
O mestre confirma a transação de inserção.
O cliente recebe a resposta do mestre (sucesso).
Depois que o evento entra no log de retransmissão, o encadeamento SQL escravo executa
o evento. O mestre e o cliente não sabem se a execução foi bem-sucedida ou não.
A replicação semi-síncrona resolveu um caso importante quando o escravo ou a rede morreu e o mestre continuou a prosseguir. O mestre morre e você deseja reiniciar o antigo escravo como novo mestre apenas porque você corrigiu esse nó.
Então você iniciou esse nó como novo mestre, corrigiu o antigo mestre e agora deseja usá-lo como escravo. Esse nó ainda possui os dados, mas se o novo escravo iniciar da posição em que o novo mestre foi iniciado, haverá registros duplicados.
Se o período de espera for infinito, a posição do log binário mestre sempre estará sincronizada com a posição do log do relé escravo, assumindo que todas as consultas no escravo foram bem-sucedidas. Quão realista é essa suposição?
Eu acho isso muito realista. Um dos casos mais comuns de falha na consulta escrava é "registro duplicado". Onde o registro duplicado chegou ao escravo se o mestre não o possuía? Veio da posição errada dada ao escravo para começar a se replicar. A posição de replicação inicial incluía o registro que já estava replicado. No caso de replicação semi-síncrona, essa situação não ocorrerá.
Jacob Nikom
fonte
Qualificador : Eu não sou usuário do MySQL, então, principalmente, esta é apenas minha pesquisa na Internet.
Como eu tenho certeza que você sabe, a maior limitação da replicação do MySQL é que ela é de thread único. Portanto, enquanto o encadeamento estiver ocupado enviando dados para o escravo interno, ele não poderá enviar dados para o escravo remoto. Isto é por aqui .
Por aqui :
Uma coisa que você precisa fazer é reduzir o tempo de transação. Isso permite que seu segmento de replicação tenha a oportunidade de acompanhar o que está acontecendo no banco de dados. Você deseja que suas transações sejam o mais curtas possível.
Uma maneira de fazer isso é através do corte de consultas; limite as linhas alteradas por UPDATE ou DELETE através do uso das cláusulas WHERE. Se você colocar isso dentro de um loop, poderá percorrer a lista, iniciando e confirmando a transação a cada vez. (ATUALIZE / DELETE o primeiro terço, o segundo terço e o terço final, cada um em sua própria transação.) Pessoalmente, aconselho fortemente que não faça isso porque você se abre para a possibilidade de os dados na tabela mudarem entre transações. Mas, é uma possibilidade de melhorar esse desempenho se você tiver certeza de que ninguém mais está mexendo com a tabela (e nunca o fará) .
Outra possibilidade é não replicar essas transações demoradas, mas executá-las no mestre (que replica no escravo local) e depois executá-las no escravo remoto separadamente. Isso liberaria o encadeamento de replicação para que não atinja a marca de mais de 30 minutos.
Por aqui :
Uma possibilidade final seria ajustar o tamanho dos seus buffers TCP. O objetivo é reduzir o número de comunicações que você está fazendo entre o mestre e o escravo. Isso pode ajudar a reduzir a latência.
Pessoalmente, eu tentaria isso se tudo mais falhar. Suspeito que o problema seja mais causado pelo sistema de replicação de thread único do que pela latência da rede. As redes normalmente atingiam o tempo limite muito antes da marca dos 30 minutos. (30 minutos?!)
Os favoritos do JHammerb Delicious têm vários links para replicação mysql que você também pode conferir.
Espero que ajude.
fonte