Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

O que há de novo com a replicação do MySQL no MySQL 8.0


A replicação no MySQL existe há muito tempo e vem melhorando constantemente ao longo dos anos. Tem sido mais como evolução do que revolução. Isso é perfeitamente compreensível, pois a replicação é um recurso importante do qual muitos dependem - tem que funcionar.

Nas últimas versões do MySQL, vimos melhorias no desempenho da replicação por meio do suporte à aplicação de transações em paralelo. No MySQL 5.6, a paralelização era feita no nível do esquema - todas as transações que foram executadas em esquemas separados podiam ser executadas de uma só vez. Essa foi uma boa melhoria para as cargas de trabalho que tinham vários esquemas em um único servidor, e a carga foi distribuída de forma mais ou menos uniforme entre os esquemas.

No MySQL 5.7, outro método de paralelização foi adicionado, o chamado “relógio lógico”. Permitiu obter algum nível de simultaneidade em um escravo, mesmo que todos os seus dados tenham sido armazenados em um único esquema. Foi baseado, em suma, no fato de que algumas transações seriam confirmadas juntas por causa de uma latência adicionada pelo hardware. Você pode até adicionar essa latência manualmente, para obter uma melhor paralelização nos escravos usando binlog_group_commit_sync_delay.

Esta solução foi muito boa, mas não sem inconvenientes. Cada atraso na confirmação de uma transação pode afetar as partes do aplicativo voltadas para o usuário. Claro, você pode definir atrasos em um intervalo de vários milissegundos, mas, mesmo assim, é a latência adicional que diminui a velocidade do aplicativo.

Melhorias de desempenho de replicação no MySQL 8.0


O MySQL 8.0, que a partir de agora (agosto de 2017) ainda está em estado beta, traz algumas boas melhorias para a replicação. Originalmente, ele foi desenvolvido para replicação de grupo (GR), mas como o GR usa replicação regular sob o capô, a replicação "normal" do MySQL se beneficiou disso. A melhoria que mencionamos são as informações de rastreamento de dependência armazenadas no log binário. O que acontece é que o MySQL 8.0 agora tem uma maneira de armazenar informações sobre quais linhas foram afetadas por uma determinada transação (o chamado conjunto de gravação) e compara conjuntos de gravação de diferentes transações. Isso permite identificar as transações que não funcionaram no mesmo subconjunto de linhas e, portanto, podem ser aplicadas em paralelo. Isso pode permitir aumentar o nível de paralelização em várias vezes em comparação com a implementação do MySQL 5.7. O que você precisa ter em mente é que, eventualmente, um escravo verá uma visão diferente dos dados, uma que nunca apareceu no mestre. Isso ocorre porque as transações podem ser aplicadas em uma ordem diferente da do mestre. Isso não deve ser um problema embora. A implementação atual de replicação multithread no MySQL 5.7 também pode causar esse problema, a menos que você habilite explicitamente slave-preserve-commit-order.

Para controlar esse novo comportamento, uma variável binlog_transaction_dependency_tracking foi introduzido. Pode assumir três valores:
  • COMMIT_ORDER:este é o padrão, usa o mecanismo padrão disponível no MySQL 5.7.
  • WRITESET:Permite uma melhor paralelização e o mestre passa a armazenar os dados do writeset no log binário.
  • WRITESET_SESSION:Isso garante que as transações serão executadas no escravo em ordem e o problema com um escravo que vê um estado de banco de dados que nunca foi visto no mestre é eliminado. Ele reduz a paralelização, mas ainda pode fornecer uma taxa de transferência melhor do que as configurações padrão.

Referência


Em julho, no mysqlhighavailability.com, Vitor Oliveira escreveu um post onde tentava medir o desempenho dos novos modos. Ele usou o melhor cenário - sem durabilidade alguma, para mostrar a diferença entre os modos antigo e novo. Decidimos usar a mesma abordagem, desta vez em uma configuração mais real:log binário habilitado com log_slave_updates. As configurações de durabilidade foram deixadas para o padrão (portanto, sync_binlog=1 - esse é o novo padrão no MySQL 8.0, buffer de escrita dupla habilitado, somas de verificação InnoDB habilitadas etc.) A única exceção em durabilidade foi innodb_flush_log_at_trx_commit definido como 2.

Usamos instâncias m4.2xl, 32G, 8 núcleos (portanto, slave_parallel_workers foi definido como 8). Também usamos o script sysbench, oltp_read_write.lua. 16 milhões de linhas em 32 tabelas foram armazenadas em um volume gp2 de 1.000 GB (ou seja, 3.000 IOPS). Testamos o desempenho de todos os modos para 1, 2, 4, 8, 16 e 32 conexões simultâneas do sysbench. O processo foi o seguinte:parar o escravo, executar 100k transações, iniciar o escravo e calcular quanto tempo leva para limpar o atraso do escravo.

Em primeiro lugar, não sabemos realmente o que aconteceu quando o sysbench foi executado usando apenas 1 thread. Cada teste foi executado cinco vezes após uma corrida de aquecimento. Essa configuração específica foi testada duas vezes - os resultados são estáveis:a carga de trabalho de thread único foi a mais rápida. Estaremos analisando mais a fundo para entender o que aconteceu.

Fora isso, o restante dos resultados está em linha com o que esperávamos. COMMIT_ORDER é o mais lento, especialmente para baixo tráfego, 2-8 threads. WRITESET_SESSION normalmente tem um desempenho melhor que COMMIT_ORDER, mas é mais lento que WRITESET para tráfego de baixa concorrência.

Como ele pode me ajudar?


A primeira vantagem é óbvia:se sua carga de trabalho estiver lenta, mas seus escravos tiverem tendência a retroceder na replicação, eles poderão se beneficiar de um desempenho de replicação aprimorado assim que o mestre for atualizado para 8.0. Duas notas aqui:primeiro - esse recurso é compatível com versões anteriores e os escravos 5.7 também podem se beneficiar dele. Segundo - um lembrete de que o 8.0 ainda está em estado beta, não incentivamos você a usar software beta em produção, embora em extrema necessidade, esta é uma opção para testar. Esse recurso pode ajudá-lo não apenas quando seus escravos estão atrasados. Eles podem ser totalmente recuperados, mas quando você cria um novo escravo ou reprovisiona um existente, esse escravo estará atrasado. Ter a capacidade de usar o modo “WRITESET” tornará o processo de provisionamento de um novo host muito mais rápido.

Em suma, esse recurso terá um impacto muito maior do que você imagina. Dado todos os benchmarks mostrando regressões no desempenho quando o MySQL lida com tráfego de baixa simultaneidade, qualquer coisa que possa ajudar a acelerar a replicação em tais ambientes é uma grande melhoria.

Se você usa mestres intermediários, esse também é um recurso a ser procurado. Qualquer mestre intermediário adiciona alguma serialização em como as transações são tratadas e executadas - no mundo real, a carga de trabalho em um mestre intermediário quase sempre será menos paralela do que no mestre. A utilização de writesets para permitir uma melhor paralelização não apenas melhora a paralelização no mestre intermediário, mas também pode melhorar a paralelização em todos os seus escravos. É até possível (embora exija testes sérios para verificar se todas as peças se encaixam corretamente) usar um mestre intermediário 8.0 para melhorar o desempenho de replicação de seus escravos (por favor, lembre-se de que o escravo do MySQL 5.7 pode entender os dados do conjunto de gravação e usá-lo mesmo que ele não pode gerá-lo por conta própria). Claro, replicar de 8.0 para 5.7 parece bastante complicado (e não é apenas porque 8.0 ainda é beta). Em algumas circunstâncias, isso pode funcionar e pode acelerar a utilização da CPU em seus escravos 5.7.

Outras mudanças na replicação do MySQL


A introdução de writesets, embora seja a mais interessante, não é a única mudança que aconteceu na replicação do MySQL no MySQL 8.0. Vamos passar por algumas outras mudanças, também importantes. Se você usar um mestre anterior ao MySQL 5.0, o 8.0 não suportará seu formato de log binário. Não esperamos ver muitas dessas configurações, mas se você usa algum MySQL muito antigo com replicação, definitivamente é hora de atualizar.

Os valores padrão foram alterados para garantir que a replicação seja o mais segura possível contra falhas:master_info_repository e relay_log_info_repository são definidos como TABELA. Expire_log_days também foi alterado - agora o valor padrão é 30. Além de expire_log_days , uma nova variável foi adicionada, binlog_expire_log_seconds , que permite uma política de rotação de log binário mais refinada. Alguns carimbos de data/hora adicionais foram adicionados ao log binário para melhorar a observabilidade do atraso de replicação, introduzindo a granularidade de microssegundos.

Por todos os meios, esta não é uma lista completa de alterações e recursos relacionados à replicação do MySQL. Se você quiser saber mais, você pode verificar os changelogs do MySQL. Certifique-se de revisar todos eles - até agora, os recursos foram adicionados em todas as versões 8.0.

Como você pode ver, a replicação do MySQL ainda está mudando e se tornando melhor. Como dissemos no início, tem que ser um processo lento, mas é muito bom ver o que está por vir. Também é bom ver o trabalho da Replicação de Grupo diminuindo e sendo reutilizado na replicação “regular” do MySQL.