Prestazioni di replica di MySQL


15

Sto riscontrando un serio problema con le prestazioni di replica di MySQL 5.5 tra due macchine, principalmente tabelle myISAM con replica basata su istruzioni. I registri binari e la directory dei dati mysql si trovano entrambi sullo stesso Fusion ioDrive.

Il problema è stato recentemente un grosso problema quando abbiamo dovuto mettere in pausa la replica per ca. 3 ore. Ci sono volute circa 10 ore per recuperare di nuovo senza altri carichi.

10 ore per recuperare

Come posso aumentare le prestazioni della replica? La macchina B è sostanzialmente inattiva (poca, IO, 2 core su 16, molta RAM libera), poiché solo 1 thread mySQL stava scrivendo dati. Ecco alcune idee che ho avuto:

  • Passa alla replica basata su righe. Nei test questo ha prodotto solo un aumento delle prestazioni del 10-20%
  • Aggiornamento a mySQL 5.6 con replica multi-thread. Potremmo facilmente dividere i nostri dati in database separati e i benchmark sembrano indicare che ciò potrebbe aiutare, ma il codice non sembra pronto per la produzione.
  • Alcune variabili di configurazione che aiuteranno ad accelerare la replica

Il problema principale è che se ci vogliono 10 ore per recuperare dopo aver messo in pausa per 3 ore, ciò significa che la replica sta scrivendo 13 ore di dati in 10 ore o è in grado di scrivere al 130% della velocità dei dati in arrivo. Sto cercando di almeno doppie scritture sulla macchina Master nel prossimo futuro, quindi hanno un disperato bisogno di un modo per migliorare le prestazioni di replica.

Macchina A:

  • Maestro
  • Ram da 24 GB
  • 1.2 TB Fusion ioDrive2
  • 2x E5620
  • Interconnessione 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

Macchina B:

  • Schiavo
  • Ram da 36 GB
  • 1.2 TB Fusion ioDrive2
  • 2x E5620
  • Interconnessione 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

La macchina B è sostanzialmente inattiva . Questa è la mia esperienza con la replica su MySQL 5.1. La replica è a thread singolo e una CPU verrà massimizzata mentre le altre resteranno inattive.
Stefan Lasiewski,

stai facendo dei backup dallo slave?
Mike,

@ stefan-lasiewski Per essere chiari, questo è MySQL 5.5, ma sì. È a thread singolo e molto frustrante
Nick,

@ Mike Sì, così come le domande pesanti che richiedono molti minuti durante il giorno. La replica rallenta a circa 100 secondi circa, quindi impiega un po 'di tempo per recuperare di nuovo. Il servizio che esegue queste query eseguirà una query, aspetterà che raggiunga, quindi eseguirà un'altra, aspetta, ecc ... Se siamo in grado di accelerare la replica, possiamo aumentare la frequenza con cui eseguiamo queste query
Nick

1
@ stefan-lasiewski Sì - Se nulla blocca la replica, ovviamente non rimarrà indietro. Il problema principale è che la velocità di replica è un collo di bottiglia per aumentare le scritture sul master. Se ci vogliono 3.3s per raggiungere 1s, ciò significa che la replica sta scrivendo 4.3s di dati in 3.3s, o è in grado di replicare solo al 130% della velocità dei dati che arrivano. Sto cercando di almeno raddoppiare la scrittura caricare su questo server.
Nick,

Risposte:


4

Wow, hai dell'hardware terribilmente robusto per questo problema. Non c'è molto di più che si possa considerare dal punto di vista hardware, ad eccezione dell'aggiornamento a forse le CPU Sandy / Ivy Bridge per prestazioni migliori del 20-50% rispetto alle ricerche Btree, ecc.

Nota che il mio forte è Innodb, quindi lo farò

  1. Ignora che sei myisam e agisci come se non facesse la differenza.
  2. Supponiamo che questo problema sia sufficiente per farti aggiornare. Sì, è un aggiornamento.

Innodb può aiutare a sfruttare al meglio tutta quella memoria memorizzando queste righe a cui si accede frequentemente nel suo pool di buffer. Puoi ottimizzarlo per essere grande quanto vuoi (diciamo l'80% della memoria) e le letture / scritture nuove rimangono in memoria fino a quando non è necessario spingerle sul disco per fare spazio agli ultimi dati a cui si accede. In memoria è un ordine di grandezza più veloce dei tuoi FusionIO.

Esistono molte altre funzionalità di Innodb, come hash adattivi, meccanismi di blocco automatico, ecc. Che possono essere un vantaggio per il tuo ambiente. Tuttavia, conosci i tuoi dati meglio di me.

Nel mondo innodb, una buona soluzione a breve termine è quella di ottimizzare il tuo slave: hai davvero bisogno di ogni indice sul tuo slave che hai sul tuo master? Gli indici sono una palla a catena su inserti / aggiornamenti / eliminazioni, ANCHE con schede IO Fusion. IOPS non sono tutto qui. I processori Sandy / Ivy bridge hanno una memoria e prestazioni di calcolo molto migliori: possono fare una grande differenza per i Westmer che hai ora. (Figura 20-50% complessivo). Rimuovi tutti gli indici che non ti servono sullo slave!

Secondo, e quasi certamente si applica solo a innodb, è che mk-prefetch può sapere quali aggiornamenti e prima che lo slave li scriva. Ciò consente a mk-prefetch di eseguire prima una query di lettura, forzando in tal modo i dati in memoria quando il singolo sostituto esegue la query di scrittura. Ciò significa che i dati sono in memoria e non in fusionIO, un rapido ordine di guadagno delle prestazioni di grandezza. Questo fa una GRANDE differenza, più di quanto ci si potrebbe aspettare. Molte aziende lo usano come soluzione permanente. Per saperne di più, consulta Percona Toolkit .

Terzo, e soprattutto, dopo aver effettuato l'aggiornamento a Innodb, dai un'occhiata a Tokutek. Questi ragazzi hanno delle cose terribilmente fantastiche che superano le prestazioni di scrittura / aggiornamento / eliminazione di Innodb da un colpo lungo. Hanno promosso una maggiore velocità di replica come uno dei vantaggi chiave e dai loro parametri di riferimento è possibile capire perché IOPS pazzi di Fusions non ti aiuterà ancora nel caso di Btrees . (Nota: non verificato da me in modo indipendente.) Usano un drop-in sostituto di un indice btree che, sebbene orribilmente più complesso, migliora molti dei limiti di velocità algoritmica degli indici btree.

Sono in procinto di prendere in considerazione l'adozione di Tokutek. Se liberano tanta velocità di scrittura, ciò mi consente di aggiungere più indici. Dato che comprimono i dati e gli indici a rapporti così meravigliosi (25 volte citano), non si paga nemmeno un prezzo (prestazioni, manutenzione) per aumentare i dati. Paghi ($) per il loro motore, $ 2500 / anno per GB precompresso, IIRC. Hanno sconti se hai i dati replicati, ma puoi anche semplicemente installare Tokutek sul tuo slave e mantenere il tuo master così com'è. Consulta i dettagli tecnici nella lezione del MIT Algoritms Open Courseware . In alternativa, hanno tonnellate di materiale tecnico sul loro blog e white paper regolari per coloro che non hanno 1:20 per guardare il video. Credo che questo video fornisca anche la formula Big-O per quanto sono veloci le letture. Io hosupporre che le letture siano più lente (c'è sempre un compromesso!), ma la formula è troppo complessa per me per valutare quanto. Sostengono che è più o meno la stessa cosa, ma preferirei capire la matematica (probabilmente non!). Potresti trovarti in una situazione migliore per scoprirlo di me.

Ps Non sono affiliato con Tokutek, non ho mai eseguito il loro prodotto e non sanno nemmeno che li sto guardando.

Aggiornamento :

Vedo che hai altre domande su questa pagina e ho pensato di aggiungere:

Innanzitutto, il pre-fetch degli schiavi non funzionerà quasi certamente per myisam a meno che non si abbia un ambiente eccezionale. Ciò è principalmente dovuto al fatto che il prefetching bloccherà proprio le tabelle in cui si intende scrivere, oppure il thread slave ha la tabella bloccata di cui il demone pre-fetch ha bisogno. Se le tue tabelle sono estremamente ben bilanciate per la replica e vengono scritte diverse tabelle in modo round robin, questo può funzionare - ma tieni presente che è molto teorico. Il libro "High Performance Mysql" contiene ulteriori informazioni nella sezione "Problemi di replica".

In secondo luogo, presumibilmente il tuo slave ha un carico di 1,0-1,5, potrebbe essere più alto se hai altri proc o query in esecuzione ma una baseline di 1.0. Ciò significa che probabilmente sei legato alla CPU, il che è probabile con FusionIO integrato. Come ho detto prima, Sandy / Ivy Bridge darà un po 'più di brio, ma probabilmente non abbastanza per superare i tempi più difficili con un ritardo minimo. Se il carico su questo slave è per lo più di sola scrittura (cioè non molte letture), la CPU sta quasi sicuramente impiegando il suo tempo a calcolare le posizioni per inserimenti / eliminazioni btree. Questo dovrebbe rafforzare il mio punto sopra sulla rimozione di indici non critici: puoi sempre aggiungerli di nuovo in un secondo momento. Disabilitare l'hyperthreading non funzionerà, più CPU non è il tuo nemico. Una volta superati i 32 GB di RAM, diciamo 64 GB, devi preoccuparti della distribuzione delle ram, ma anche allora i sintomi sono diversi.

Infine, e soprattutto (non saltare questa parte;)), presumo che ora stai eseguendo RBR (replica basata su righe) perché hai menzionato un aumento delle prestazioni non banale quando lo hai cambiato. Tuttavia, potrebbe esserci un modo per ottenere prestazioni ancora maggiori qui. Il bug 5q75 di Mysql può manifestarsi se hai tabelle replicate senza chiave primaria. Lo slave non è fondamentalmente abbastanza intelligente da utilizzare qualsiasi cosa tranne una chiave primaria, quindi l'assenza di uno forza il thread di replica a eseguire una scansione della tabella completa per ogni aggiornamento. Una correzione consiste semplicemente nell'aggiungere una chiave primaria autoincrementante benigna e surrogata. Lo farei solo se la tabella fosse grande (diciamo più di 10 o migliaia di righe). Questo, ovviamente, ha il costo di avere un altro indice sul tavolo, il che fa apparire il prezzo da pagare in CPU. Nota che ci sono pochissimi argomenti teorici contro questo, poiché InnoDB ne aggiunge uno dietro le quinte se non lo fai. Quello fantasma, però, non è una difesa utile contro 53375. tungsteno in grado di superare anche questo problema, ma è necessario per essere sicuri quando si utilizza tungsteno che avete la vostra codifica dritto. L'ultima volta che ci ho giocato, sarebbe morto in modo orribile quando ogni stringa non UTF8 doveva essere replicata. Questo è il momento in cui mi sono arreso.


Grazie mille per il tuo tempo! Apprezzo molto le informazioni che hai fornito qui. Il passaggio a InnoDB era qualcosa che stavamo prendendo in considerazione da un po ', principalmente per i vantaggi del blocco a livello di riga. Questo mi dà qualche spunto di riflessione. Grazie ancora.
Nick,

Wow, questa è un'analisi mysql davvero geniale :)
Kevin,

4

non è una risposta, ma potresti considerare il replicatore di tungsteno e i suoi prodotti commerciali per una maggiore flessibilità. è il 100% di utilizzo della CPU su single core che è il collo di bottiglia?


Grazie! Questa è una soluzione interessante, anche se sono un po 'titubante nel collegare software di terze parti a MySQL. Nei documenti dice "Non è necessario eseguire l'aggiornamento per attendere future versioni di MySQL o migrare verso alternative non testate", quindi sembra essere simile a ciò che MySQL 5.6 avrà il supporto. Hai qualche esperienza con Tungsten Replicator?
Nick,

no, sappi solo che il rispettabile contributore ecosistemico mysql funziona per loro [ datacharmer.blogspot.com ]. che ne dici del collo di bottiglia - sei sicuro che sia un carico single core che è il fattore limitante?
pQd

Grazie per le informazioni. RE: il fattore limitante, no non ne sono affatto sicuro. Non penso che sia I / O, poiché iostat riporta che Fusion ioDrive sta eseguendo <10 MB / s di scritture. Sono abbastanza sicuro che il dispositivo sia in grado di fare molto di più. D'altra parte, c'è sempre 1, e in modo intermittente 1 core aggiuntivo che è ancorato al 100%, mentre gli altri sono inattivi. Che dire di disabilitare l'hyper-threading?
Nick,

@Nick - scusa, non posso consigliarti sull'hyper-threading. ma prova ... anche - prova a installare munin o cactus con modelli mysql e dai un'occhiata più in dettaglio cosa sta succedendo.
pQd

Dai un'occhiata a questo post dalla gente continua: scale-out-blog.blogspot.ca/2011/10/… Citazione: "Complessivamente possiamo tranquillamente affermare che la replica nativa a thread singolo è probabilmente non lavorabile nel limite I / O senza passare a una combinazione di SSD e / o pre-fetch slave. "
HTTP500,

2

Quindi, se si eseguono backup sullo slave ... e si utilizzano le tabelle del mioiasmo ... si stanno bloccando le tabelle per eseguire i backup per prevenire la corruzione. Quindi la replica non può funzionare fino a quando il backup non è completo .. quindi raggiunge.


Assolutamente. Blocciamo regolarmente le tabelle per backup o query lunghe, ma il problema risiede nella velocità della replica una volta ripreso il thread IO. Stimo che si sta replicando solo al 130% della velocità dei dati in arrivo, il che limita quanto più lontano possiamo ridimensionare questa configurazione a meno che non possiamo migliorare la velocità di replica. Ha senso?
Nick,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.