Desempenho de replicação do MySQL

15

Estou tendo um problema sério com o desempenho de replicação do MySQL 5.5 entre duas máquinas, principalmente tabelas myISAM com replicação baseada em instruções. Os logs binários e o diretório de dados do mysql estão localizados no mesmo Fusion ioDrive.

O problema foi um grande problema recentemente, quando precisávamos pausar a replicação por aprox. 3 horas. Demorou cerca de 10 horas para recuperar o atraso sem outra carga.

10 horas para recuperar o atraso

Como posso aumentar o desempenho da replicação? A máquina B está basicamente ociosa (pouco, IO, 2 núcleos no máximo de 16, muita RAM livre), pois apenas 1 thread do mySQL estava gravando dados. Aqui estão algumas idéias que tive:

  • Alterne para replicação baseada em linha. Nos testes, isso gerou apenas um aumento de desempenho de 10 a 20%
  • Atualize para o mySQL 5.6 com replicação multithread. Poderíamos facilmente dividir nossos dados em bancos de dados separados, e os benchmarks parecem indicar que isso ajudaria, mas o código não parece pronto para produção.
  • Algumas variáveis ​​de configuração que ajudarão a acelerar a replicação

O principal problema é que, se levar 10h para recuperar o atraso após uma pausa de 3h, isso significa que a replicação está gravando 13h de dados em 10h ou é capaz de gravar a 130% da velocidade dos dados recebidos. Estou procurando pelo menos, duplas gravações na máquina Master em um futuro próximo, portanto, é necessário desesperadamente uma maneira de melhorar o desempenho da replicação.

Máquina A:

  • mestre
  • 24GB de RAM
  • 1.2TB Fusion ioDrive2
  • 2x E5620
  • Interconexão Gigabit

my.cnf:

[mysqld]
server-id=71
datadir=/data_fio/mysqldata
socket=/var/lib/mysql/mysql.sock
tmpdir=/data_fio/mysqltmp

log-error = /data/logs/mysql/error.log
log-slow-queries = /data/logs/mysql/stats03-slowquery.log
long_query_time = 2
port=3306

log-bin=/data_fio/mysqlbinlog/mysql-bin.log
binlog-format=STATEMENT
replicate-ignore-db=mysql

log-slave-updates = true

# Performance Tuning
max_allowed_packet=16M
max_connections=500
table_open_cache = 2048
max_connect_errors=1000
open-files-limit=5000

# mem = key_buffer + ( sort_buffer_size + read_buffer_size ) * max_connections
key_buffer=4G
max_heap_table_size = 1G
tmp_table_size = 4G
myisam_sort_buffer_size = 256M
sort_buffer_size=4M
read_buffer_size=2M
query_cache_size=16M
query_cache_type=2
thread_concurrency=32

user=mysql

symbolic-links=0

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[mysql]
socket=/var/lib/mysql/mysql.sock

[client]
socket=/var/lib/mysql/mysql.sock

Máquina B:

  • Escravo
  • 36GB de RAM
  • 1.2TB Fusion ioDrive2
  • 2x E5620
  • Interconexão Gigabit

my.cnf:

[mysqld]
server-id=72
datadir=/data_fio/mysqldata
socket=/var/lib/mysql/mysql.sock
tmpdir=/data_fio/mysqltmp

log-error = /data/logs/mysql/error.log
log-slow-queries = /data/logs/mysql/stats03-slowquery.log
long_query_time = 2
port=3306

# Performance Tuning
max_allowed_packet=16M
max_connections=500
table_open_cache = 2048
max_connect_errors=1000
open-files-limit=5000

# mem = key_buffer + ( sort_buffer_size + read_buffer_size ) * max_connections
key_buffer=4G
max_heap_table_size = 1G
tmp_table_size = 4G
myisam_sort_buffer_size = 256M
sort_buffer_size=4M
read_buffer_size=2M
query_cache_size=16M
query_cache_type=2
thread_concurrency=32

user=mysql

symbolic-links=0

plugin-load=archive=ha_archive.so;blackhole=ha_blackhole.so

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

[mysql]
socket=/var/lib/mysql/mysql.sock

[client]
socket=/var/lib/mysql/mysql.sock
usuario
fonte
A máquina B está basicamente ociosa . Esta é minha experiência com replicação no MySQL 5.1. A replicação é de thread único e uma CPU será maximizada enquanto as outras ficarão ociosas.
23812 Stefan Lasiewski
você está fazendo backups do escravo?
21712 Mike
@ stefan-lasiewski Para ser claro, este é o MySQL 5.5, mas sim. É single-threaded e muito frustrante
Nick
@ Mike Sim, bem como consultas pesadas que levam muitos minutos ao longo do dia. A replicação diminui para aproximadamente 100s e demora um pouco para recuperar o atraso. O serviço que executa essas consultas executa uma consulta, aguarda a atualização, executa outra, espera, etc ... Se conseguirmos acelerar a replicação, podemos aumentar a frequência com que executamos essas consultas
Nick
1
@ stefan-lasiewski Sim - Se nada parar a replicação, obviamente não ficará para trás. O principal problema é que a velocidade de replicação é um gargalo para aumentar as gravações no mestre. Se forem necessários 3,3s para recuperar 1s, isso significa que a replicação está gravando 4,3s de dados no 3,3s ou é capaz de replicar apenas 130% da velocidade dos dados recebidos. Estou procurando pelo menos gravar duas vezes carregar neste servidor.
21412 Nick

Respostas:

4

Uau, você tem algum hardware extremamente robusto para esse problema. Não há muito mais que você possa usar em termos de hardware, com exceção da atualização para as CPUs Sandy / Ivy Bridge para obter um desempenho 20-50% melhor nas pesquisas da Btree, etc.

Por favor, note que meu forte é Innodb, então eu vou

  1. Ignore que você é myisam e aja como se não fizesse diferença.
  2. Suponha que esse problema seja suficiente para fazer a atualização. Sim, é uma atualização.

O Innodb pode ajudar a tirar grande proveito de toda essa memória armazenando essas linhas acessadas com frequência em seu buffer pool. Você pode ajustá-lo para o tamanho que desejar (digamos 80% da memória) e novas leituras / gravações permanecem na memória até que seja necessário enviá-las para o disco para liberar mais espaço para os dados mais recentes acessados. A memória é uma ordem de magnitude mais rápida que seus FusionIOs.

Existem muitos outros recursos do Innodb, como hashes adaptáveis, mecanismos de travamento automático, etc. que podem ser um benefício para o seu ambiente. Você, no entanto, conhece seus dados melhor do que eu.

No mundo innodb, uma boa solução a curto prazo é otimizar seu escravo - você realmente precisa de todos os índices do seu escravo que possui no seu mestre? Os índices são uma bola e uma corrente nas inserções / atualizações / exclusões, MESMO com os cartões Fusion IO. IOPS não são tudo aqui. Os processos de ponte Sandy / Ivy têm uma taxa de transferência de memória e desempenho de computação muito melhores - eles podem fazer uma enorme diferença no Westmeres que você tem agora. (Figura 20-50% do total). Remova todos os índices que você não precisa no escravo!

Segundo, e quase certamente se aplica apenas ao innodb, é que o mk-prefetch pode saber quais atualizações e antes que o escravo as grave. Isso permite que o mk-prefetch execute uma consulta de leitura primeiro, forçando os dados a ficarem na memória no momento em que a única substituição executa a consulta de gravação. Isso significa que os dados estão na memória e não no fusionIO, um rápido ganho de desempenho em ordem de magnitude. Isso faz uma enorme diferença, mais do que se poderia esperar. Muitas empresas usam isso como uma solução permanente. Saiba mais consultando o Percona Toolkit .

Terceiro, e mais importante, depois de atualizar para o Innodb, faça o check-out definitivo do Tokutek. Esses caras têm algumas coisas incrivelmente impressionantes que excedem em muito o desempenho de gravação / atualização / exclusão do Innodb. Eles consideram a velocidade de replicação aprimorada como um dos principais benefícios, e você pode ver nos seus benchmarks por que o IOPS maluco do Fusions ainda não o ajudará no caso de Btrees . (Nota: não foram verificados por mim de forma independente.) Eles usam um substituto substituto de um índice btree que, apesar de terrivelmente mais complexo, melhora muitas das limitações de velocidade algorítmica dos índices btree.

Estou pensando em adotar o Tokutek. Se eles liberam tanta velocidade de gravação, isso permite que eu adicione mais índices. Como eles compactam os dados e os índices em proporções maravilhosas (25x, eles citam), você nem paga um preço (desempenho, manutenção) por um aumento de dados. Você paga ($) pelo mecanismo, no entanto, US $ 2500 / ano por GB pré-compactado, IIRC. Eles têm descontos se você replicar os dados, mas você pode até instalar o Tokutek no seu escravo e manter o seu mestre como está. Confira os detalhes técnicos na palestra MIT Algoritms Open Courseware . Como alternativa, eles têm toneladas de material técnico em seu blog e whitepapers regulares para quem não tem 1:20 para assistir ao vídeo. Acredito que este vídeo também fornece a fórmula Big-O para a rapidez com que as leituras são. Eu tenhosupor que as leituras são mais lentas (sempre há uma troca!), mas a fórmula é muito complexa para eu avaliar quanto. Eles alegam que é aproximadamente o mesmo, mas eu prefiro entender a matemática (provavelmente não!). Você pode estar em uma situação melhor para descobrir isso do que eu.

Ps: Eu não sou afiliado à Tokutek, nunca usei o produto deles e eles nem sabem que eu estou olhando para eles.

Atualização :

Vejo que você tem outras perguntas nesta página e pensei em inserir:

Primeiro, a pré-busca de escravos quase certamente não funcionará para o myisam, a menos que você tenha um ambiente excepcional. Isso ocorre principalmente porque a pré-busca bloqueará as próprias tabelas nas quais você pretende gravar ou o encadeamento escravo tem a tabela bloqueada que o daemon de pré-busca precisa. Se suas tabelas são extremamente bem equilibradas para replicação e tabelas diferentes estão sendo gravadas de maneira round-robin, isso pode funcionar - mas lembre-se de que isso é muito teórico. O livro "Mysql de alto desempenho" possui mais informações na seção "Problemas de replicação".

Segundo, presumivelmente o seu escravo mantém uma carga de 1,0 a 1,5, pode ser maior se você tiver outros procs ou consultas em execução, mas uma linha de base de 1,0. Isso significa que você provavelmente está vinculado à CPU, o que provavelmente ocorre com o seu FusionIO a bordo. Como mencionei anteriormente, Sandy / Ivy Bridge vai dar um pouco mais de força, mas provavelmente não o suficiente para passar pelos tempos mais difíceis com um atraso mínimo. Se a carga neste escravo é principalmente somente de gravação (ou seja, não há muitas leituras), sua CPU está quase certamente gastando seu tempo calculando posições para inserções / exclusões de btree. Isso deve reforçar meu argumento acima sobre a remoção de índices não críticos - você sempre pode adicioná-los novamente mais tarde. Desabilitar o hyperthreading não funcionará, mais CPU não é seu inimigo. Depois de obter mais de 32 GB de RAM, digamos 64 GB, você precisa se preocupar com a distribuição de RAM, mas mesmo assim os sintomas são diferentes.

Finalmente, e o mais importante (não pule esta parte;)), suponho que agora você esteja executando o RBR (replicação baseada em linha) porque mencionou um aumento de desempenho não trivial ao alterná-lo também. No entanto - pode haver uma maneira de obter ainda mais desempenho aqui. O bug 53375 do Mysql pode se manifestar se você tiver tabelas sendo replicadas sem chave primária. O escravo basicamente não é inteligente o suficiente para usar qualquer coisa, exceto uma chave primária; portanto, a ausência de uma força o thread de replicação a fazer uma varredura completa da tabela para cada atualização. Uma correção é simplesmente adicionar uma chave primária de aumento automático benigno e substituto. Eu faria isso apenas se a tabela fosse grande (digamos, várias dezenas de milhares de linhas ou mais). Obviamente, isso tem o custo de ter outro índice na tabela, que aumenta o preço que você paga na CPU. Observe que existem muito poucos argumentos teóricos contra isso, pois o InnoDB adiciona um nos bastidores, se não o fizer. O fantasma, no entanto, não é uma defesa útil contra o 53375. O tungstênio também pode superar esse problema, mas você precisa ter certeza de que, ao usar o tungstênio, sua codificação está correta. A última vez que joguei com ele, morreria horrivelmente quando qualquer sequência não UTF8 precisava ser replicada. Foi nessa época que desisti.

fimbulvetr
fonte
Muito obrigado pelo seu tempo! Eu realmente aprecio as informações que você forneceu aqui. Mudar para o InnoDB era algo que estávamos pensando há algum tempo, principalmente pelos benefícios do bloqueio no nível da linha. Isso me dá um pouco de reflexão. Obrigado novamente.
Nick
Uau, isso é alguma análise mysql seriamente brilhante :)
Kevin
4

Não é uma resposta, mas você pode considerar o replicador de tungstênio e seus produtos comerciais para obter mais flexibilidade. é o uso de 100% da CPU no núcleo único que é o gargalo?

pQd
fonte
Obrigado! Essa é uma solução interessante, embora eu esteja um pouco hesitante em conectar software de terceiros ao MySQL. Nos documentos, ele diz "Não há necessidade de atualizar para aguardar futuras versões do MySQL ou migrar para alternativas não testadas"; portanto, parece ser semelhante ao que o MySQL 5.6 terá suporte. Você tem alguma experiência com o Tungsten Replicator?
21412 Nick
não, apenas saiba que um colaborador respeitável do ecossistema mysql trabalha para eles [ datacharmer.blogspot.com ]. e quanto ao gargalo - você tem certeza de que é uma carga de núcleo único que é o fator limitante?
PQD
Obrigado pela informação. RE: o fator limitante, não, não tenho certeza. Não acho que seja E / S, pois o iostat relata que o Fusion ioDrive está fazendo <10 MB / s de gravações. Tenho certeza de que o dispositivo é capaz de muito mais. Por outro lado, sempre há 1 e, intermitentemente, 1 núcleo adicional que está atrelado a 100%, enquanto os outros estão ociosos. Que tal desabilitar o hyper-threading?
21412 Nick
@ Nick - desculpe, eu não posso aconselhar sobre hyper-threading. mas tente ... também - tente instalar munin ou cacti com modelos mysql e dê uma olhada mais em detalhes sobre o que está acontecendo.
PQD
Confira esta postagem do pessoal do Continuent: scale-out-blog.blogspot.ca/2011/10/… Citação: "No geral, podemos dizer com segurança que a replicação nativa de thread único provavelmente não pode ser trabalhada no I / O-bound caso sem precisar de uma combinação de SSDs e / ou pré-busca do escravo. "
HTTP500
2

Portanto, se você estiver fazendo backups no escravo ... e usar tabelas de miiasmo ... estará bloqueando as tabelas para fazer backups para evitar corrupção. Portanto, a replicação não pode funcionar até que o backup seja concluído.

Mike
fonte
Absolutamente. Bloqueamos regularmente tabelas para backups ou consultas longas, mas o problema está na velocidade da replicação assim que o encadeamento de E / S é retomado. Eu estimo que ele está apenas replicando a 130% da velocidade dos dados que chegam, o que limita quanto mais podemos escalar essa configuração, a menos que possamos melhorar a velocidade de replicação. Isso faz sentido?
21412 Nick