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.
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
fonte
Respostas:
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
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.
fonte
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?
fonte
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.
fonte