A replicação do MySQL é afetada por uma interconexão de alta latência?

11

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?

shlomoid
fonte
2000 segundos? Então, um atraso de 33 minutos?
Richard
Sim ... sobe e desce ao longo do dia.
shlomoid
2
+1 porque eu amo esses tipos de perguntas neste site. Por favor, divulgue para que outras pessoas venham a este site com perguntas dessa natureza !!!
RolandoMySQLDBA

Respostas:

7

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:

  • Mestre executa SQL
  • Evento SQL de registros mestre em seus logs binários
  • Escravo lê evento SQL de logs binários principais
  • Escravo armazena evento SQL em seus logs de retransmissão via thread de E / S
  • Escravo lê o próximo evento SQL do log de retransmissão via thread SQL
  • Escravo executa SQL
  • Escravo reconhece mestre da execução completa do evento SQL

No MySQL 5.5, usando Replicação Semissíncrona , agora a replicação operaria da seguinte maneira:

  • Mestre executa SQL
  • Evento SQL de registros mestre em seus logs binários
  • Escravo lê evento SQL de logs binários principais
  • Escravo reconhece mestre do recebimento do evento SQL
  • Escravo armazena evento SQL em seus logs de retransmissão via thread de E / S
  • Escravo lê o próximo evento SQL do log de retransmissão via thread SQL
  • Escravo executa SQL
  • Escravo reconhece mestre da execução completa do evento SQL

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

[mysqld]
plugin-dir=/usr/lib64/mysql/plugin
#rpl_semi_sync_master_enabled
#rpl_semi_sync_master_timeout=5000
#rpl_semi_sync_slave_enabled

Etapa 2) Reinicie o MySQL

service mysql restart

Etapa 3) Execute estes comandos no cliente MySQL

INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
INSTALL PLUGIN rpl_semi_sync_slave  SONAME 'semisync_slave.so';

Etapa 4) Remova o comentário das três opções rpm_semi_sync após a opção plugin-dir

[mysqld]
plugin-dir=/usr/lib64/mysql/plugin
rpl_semi_sync_master_enabled
rpl_semi_sync_master_timeout=5000
rpl_semi_sync_slave_enabled

Etapa 5) Reinicie o MySQL

service mysql restart

Tudo feito !!! Agora basta configurar o MySQL Replication como de costume.

RolandoMySQLDBA
fonte
Não tenho certeza sobre o último estágio da replicação assíncrona - não acho que o mestre saiba até que ponto cada escravo chegou. Eles podem solicitar qualquer parte do log binário que desejarem, tanto quanto eu sei - você tem alguma referência para isso?
Shlomoid #
Além disso, estamos usando a replicação assíncrona padrão no MySQL, não o tipo assíncrono - que precisa ser ativado de propósito instalando plug-ins e afins. O que estou tentando entender é se os eventos são canalizados no estilo gato de rede para o escravo a partir da posição inicial no log ou se existe uma troca entre o mestre e o escravo para cada evento, que poderia sofrer com essa latência.
Shlomoid 6/08
Por todos os meios, eu recomendo usar o MySQL 5.5 para tirar proveito desta nova forma de replicação do MySQL, bem como das melhorias do InnoDB.
RolandoMySQLDBA
1
Sim, é claro que estamos usando o MySQL 5.5, mas esse não é o tipo de replicação padrão. Você precisa passar por todo um procedimento de configuração, instalar plugins e assim por diante, para fazê-lo funcionar da maneira semi-síncrona.
Shlomoid 7/08
2

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:

  1. O cliente envia ao mestre a consulta SQL (por exemplo, inserir) usando transações

  2. O mestre executa a transação. Em caso de sucesso, o registro é armazenado no disco, mas a transação ainda não foi confirmada.

  3. 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.

  4. O cliente recebe resposta do mestre (êxito ou reversão).

  5. 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.

  6. O encadeamento de E / S escrava recebe o evento e o grava no final do arquivo de log de retransmissão.

  7. 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:

  1. O cliente envia ao mestre a consulta SQL (por exemplo, inserção) usando transações.

  2. O mestre executa a transação. Em caso de sucesso, o registro é armazenado no disco, mas a transação não é confirmada.

  3. 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.

  4. 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.

  5. O encadeamento de E / S escrava recebe o evento e o grava no final do arquivo de log de retransmissão.

  6. Escravo Reconhece o mestre da gravação do evento no arquivo de log de retransmissão.

  7. O mestre confirma a transação de inserção.

  8. O cliente recebe a resposta do mestre (sucesso).

  9. 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

Jacob Nikom
fonte
1

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.

Richard
fonte
1
Você recebe um +1 por mencionar como a replicação do MySQL é de thread único, mas eu preciso qualificar sua declaração da seguinte maneira: A replicação do MySQL é de thread duplo usando um thread de E / S para baixar eventos SQL do Master para Slave e um thread SQL para processamento os eventos SQL localmente no escravo. No entanto, a transmissão dos Eventos SQL é de thread único, o que é contextualmente correto para esta pergunta.
RolandoMySQLDBA
2
BTW Por favor, não use LIMIT com instruções UPDATE e DELETE, porque a ordem das linhas sendo atualizadas ou excluídas pode não ser a mesma no Escravo e no Mestre. Caso isso ocorra, as mensagens de aviso sobre isso aparecerão como "Declaração não segura do BinLog" no log de erros.
RolandoMySQLDBA
Ooh, bom ponto sobre não usar LIMIT com UPDATE e DELETE. Modificarei minha resposta para removê-la.
Richard