O que podemos fazer na replicação do MySQL 5.0 para solucionar problemas de largura de banda?

18

Estou desenvolvendo um aplicativo para ser executado no PC cliente (Win) configurado com uma instância do servidor MySQL 5.1 que atuará como escravo somente leitura do mestre remoto. O mestre remoto tem dezenas de esquemas, mas eu só preciso de um por cliente, portanto, forneço a configuração replication-do-db em my.ini para replicar apenas o esquema que o cliente precisa. A replicação funciona, mas quando nossos clientes acessam regiões do mundo onde o acesso à Internet só está disponível via 3G sem fio, cobrado pelo uso de dados, eles rapidamente excedem os limites do plano de dados e enfrentam problemas caros.

Pelo que entendi, o MySQL grava todas as transações para todos os esquemas em um único arquivo binlog, o que significa que cada cliente deve fazer o download de todas as transações executadas em todos os esquemas do mestre e, depois de baixado, aplicar o filtro de banco de dados por replicação. configurações do-db no arquivo my.ini do cliente.

Para minimizar essa ineficiência, empreguei a configuração slave_compressed_protocol = 1 , que parece reduzir os dados transmitidos em 50%, mas ainda faz com que nossos clientes excedam rapidamente seu limite de dados, acumulando a conta 3G.

Não consigo imaginar que sou o único a enfrentar isso, por isso tenho certeza de que receberei muitas respostas sobre como conseguir isso definindo x = y. No entanto, não consigo encontrar nenhuma documentação dessa configuração nem uma abordagem recomendada a seguir.

Até agora, aqui está o meu pensamento para uma possível solução, forneça feedback ou rotas alternativas:


  1. Configure um escravo "proxy" para cada esquema (em uma caixa diferente ou na mesma caixa com uma instância / porta MySQL diferente)
  2. Configure o escravo proxy para replicar-do-db apenas o banco de dados que os clientes desejam replicar.
  3. Configure a instância MySQL do cliente como escravos para o proxy slave apropriado.

Isso deve resultar no cliente puxando apenas os dados do binlog para seu esquema. A desvantagem (até onde eu sei) é que aumenta drasticamente a complexidade de nossa configuração, provavelmente tornando-a mais frágil.

Pensamentos? Essa abordagem funcionará?

Observe que estamos executando o servidor MySQL 5.0 no RedHat, mas poderíamos atualizar para o 5.5 se ele produzir uma solução.

Abram
fonte
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Paul White diz GoFundMonica

Respostas:

10

SUGESTÃO # 1: Usar mestres de distribuição

Um mestre de distribuição é um escravo do mysql com log-bin habilitado, atualizações de log-escravo habilitadas e contém apenas tabelas com o BLACKHOLE Storage Engine . Você pode aplicar o replicate-do-db ao mestre de distribuição e criar logs binários no mestre de distribuição que contém apenas o (s) esquema (s) do banco de dados que você deseja registrar em bin. Dessa forma, você reduz o tamanho dos binlogs de saída do mestre de distribuição.

Você pode configurar um mestre de distribuição da seguinte maneira:

  1. mysqldump seu (s) banco (s) de dados usando a opção --no-data para gerar um dump somente de esquema.
  2. Carregue o dump somente de esquema no mestre de distribuição.
  3. Converta todas as tabelas no mestre de distribuição no mecanismo de armazenamento BLACKHOLE.
  4. Configure a replicação no mestre de distribuição a partir de um mestre com dados reais.
  5. Adicione as opções replicate-do-db ao /etc/my.cnf do mestre de distribuição.

Nas etapas 2 e 3, você também pode editar o dump apenas de esquema e substituir ENGINE = MyISAM e ENGINE = InnoDB por ENGINE = BLACKHOLE e, em seguida, carregar esse dump somente de esquema editado no mestre de distribuição.

Somente na etapa 3, se você deseja criar um script para a conversão de todas as tabelas MyISAM e InnoDB para BLACKHOLE no Distribution Master, execute a seguinte consulta e envie-a para um arquivo de texto:

mysql -h... -u... -p... -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name', ENGINE=BLACKHOLE;') BlackholeConversion FROM information_schema.tables WHERE table_schema NOT IN ('information_schema','mysql') AND engine <> 'BLACKHOLE'" > BlackholeMaker.sql

Um bônus adicional ao script de conversão da tabela para o mecanismo de armazenamento BLACKHOLE é que as tabelas do mecanismo de armazenamento MEMORY também são convertidas. Embora a tabela do mecanismo de armazenamento de MEMÓRIA não ocupe espaço em disco para armazenamento de dados, ela ocupará memória. A conversão de tabelas MEMORY em BLACKHOLE manterá a memória no mestre de distribuição organizada.

Desde que você não envie nenhum DDL para o mestre de distribuição, você pode transmitir qualquer DML (INSERT, UPDATE, DELETE) que desejar antes de permitir que os clientes replicem apenas as informações de banco de dados desejadas.

Eu já escrevi uma postagem em outro site StackExchange que discute o uso de um mestre de distribuição .

SUGESTÃO # 2: Use logs binários menores e logs de retransmissão

Se você definir max_binlog_size para algo ridiculamente pequeno, os binlogs poderão ser coletados e enviados em pedaços menores. Há também uma opção separada para definir o tamanho dos logs de retransmissão, max_relay_log_size . Se max_relay_log_size = 0, será padronizado como o valor max_binlog_size configurado.

SUGESTÃO # 3: Use replicação semissíncrona (somente MySQL 5.5)

Configure seu banco de dados principal e vários Mestres de Distribuição como MySQL 5.5. Habilite a replicação semissíncrona para que o banco de dados principal possa enviar rapidamente os logs de binários para o mestre de distribuição. Se TODOS os seus escravos forem Mestres de Distribuição, talvez você não precise da Replicação Semissíncrona ou do MySQL 5.5. Se qualquer um dos escravos, que não seja o Distribution Masters, tiver dados reais para fins de geração de relatórios, alta disponibilidade, espera passiva ou backup, vá com o MySQL 5.5 em conjunto com a Replicação Semissíncrona.

SUGESTÃO # 4: Use o registro binário baseado em instruções, NÃO baseado em linhas

Se uma instrução SQL atualizar várias linhas em uma tabela, o Log Binário Baseado em Instrução (SBBL) armazenará apenas a instrução SQL. A mesma instrução SQL usando o Registro Binário Baseado em Linhas (RBBL) registrará a alteração de linha para cada linha. Isso torna óbvio que a transmissão de instruções SQL economizará espaço em logs binários que executam SBBL sobre RBBL.

Outro problema é usar o RBBL em conjunto com o replicate-do-db, em que o nome da tabela tem o banco de dados anexado . Isso não pode ser bom para um escravo, especialmente para um mestre de distribuição. Portanto, verifique se todo o DML não possui um banco de dados e um ponto na frente de nenhum nome de tabela.

RolandoMySQLDBA
fonte
Ideias interessantes @RolandoMySQLDBA, a Sugestão 1 parece com o que eu estava tentando descrever com minha configuração de escravo "proxy". No entanto, DDL é algo que eu precisarei relacionar com os escravos. Suponho que posso lidar com isso na camada de aplicativos, mas preferiria não, se puder ser evitado. Posso ver como a sugestão 2 ajudaria se o tráfego / velocidade fosse um problema, mas não tenho certeza de como ajudaria o uso da largura de banda da rede. Para a sugestão 3, você poderia elaborar um pouco para mim? Eu pensei que semissíncrona seria mais para replicação "segura" para quando você precisar saber pelo menos 1 escravo recebeu a atualização. Ótimas sugestões BTW!
Abram
@Abram Certifique-se de que os mestres de distribuição nunca recebam tabelas InnoDB ou MyISAM para limitar a E / S de disco ao gerenciamento de binlog !!!
RolandoMySQLDBA
Atualmente, estou configurando um ambiente de teste no qual terei várias instâncias do MySQL 5.5 em execução na mesma caixa (porta diff) dos mestres de distribuição. Cada mestre terá uma versão do buraco negro do respectivo banco de dados do mestre. Depois, montarei alguns escravos remotos que pendurarei no Mestre. Voltarei com meus resultados. Parece a melhor opção, embora por algum motivo eu tenha ansiedade de executar várias instâncias do MySQL. Talvez um trabalho para um servidor de micro cloud da amazon.
Abram
2
@ Abram, você deve adicionar skip-innodb ao /etc/my.cnf. Você não pode desativar o MyISAM, pois ele é um mecanismo de armazenamento de estoque. Você precisará executar manualmente ALTER TABLE tblname ENGINE = BLACKHOLE se alguma tabela em um mestre de distribuição acabar sendo MyISAM. Talvez crie um script a partir desta consulta: SELECT CONCAT ('ALTER TABLE', table_schema, '.', Table_name, 'ENGINE = BLACKHOLE;') AlterCommand FROM information_schema.tables WHERE engine = 'MyISAM' e table_schema NOT IN ('information_schema' , 'mysql'); Se você encontrar algum, basta convertê-lo na saída desta consulta.
RolandoMySQLDBA
11
Quanto à sugestão nº 3, a replicação semi-sincronizada faz com que o mestre receba o reconhecimento do escravo de que a entrada de log chegou ao escravo. No mysql 5.0, o mestre espera até que o escravo termine o processamento do SQL antes de enviar a mesma instrução para o próximo escravo. Assim, a semi-sincronização é mais rápida.
RolandoMySQLDBA
2

O max_binlog_size deve ser irrelevante - os dados do binlog são transmitidos continuamente.

Cuidado com um "mestre de distribuição" - é um "ponto único de falha". Ou seja, se ele morrer, todos os escravos que estiverem além dele não receberão dados, e a reconstrução do relé será trabalhosa.

SBR vs RBR - depende da consulta. Qualquer um pode ser melhor ou pior que o outro.

Coloque os mestres de distribuição na mesma máquina que o mestre real ou em uma máquina "próxima" do mestre. Use portas separadas para manter as instâncias separadas.

Rick James
fonte