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?


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.


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


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.


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