MySQL-Replikationsleistung


15

Ich habe ein ernstes Problem mit der MySQL 5.5-Replikationsleistung zwischen zwei Computern, hauptsächlich myISAM-Tabellen mit anweisungsbasierter Replikation. Die binären Protokolle und das MySQL-Datenverzeichnis befinden sich beide auf demselben Fusion ioDrive.

Das Problem war kürzlich ein großes Problem, als wir die Replikation für ca. 3 Stunden. Es dauerte ungefähr 10 Stunden, um ohne weitere Ladung wieder aufzuholen.

10 Stunden zum Aufholen

Wie kann ich die Leistung der Replikation steigern? Maschine B ist im Grunde untätig (wenig, E / A, 2 maximale Kerne von 16, viel freier RAM), da nur 1 mySQL-Thread Daten schrieb. Hier sind einige Ideen, die ich hatte:

  • Wechseln Sie zur zeilenbasierten Replikation. In Tests ergab dies nur eine Leistungssteigerung von 10-20%
  • Aktualisieren Sie auf mySQL 5.6 mit Multithread-Replikation. Wir könnten unsere Daten leicht in separate Datenbanken aufteilen, und Benchmarks scheinen darauf hinzudeuten, dass dies hilfreich ist, aber der Code scheint nicht produktionsbereit zu sein.
  • Einige Konfigurationsvariablen, die die Replikation beschleunigen

Das Hauptproblem ist, dass, wenn es 10 Stunden dauert, um nach einer Pause von 3 Stunden aufzuholen, dies bedeutet, dass die Replikation 13 Stunden Daten in 10 Stunden schreibt oder in der Lage ist, mit 130% der Geschwindigkeit der eingehenden Daten zu schreiben In naher Zukunft müssen mindestens zwei Schreibvorgänge auf dem Master-Computer ausgeführt werden, sodass dringend eine Möglichkeit zur Verbesserung der Replikationsleistung erforderlich ist.

Maschine A:

  • Meister
  • 24 GB RAM
  • 1,2 TB Fusion ioDrive2
  • 2x E5620
  • Gigabit-Verbindung

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

Maschine B:

  • Sklave
  • 36 GB RAM
  • 1,2 TB Fusion ioDrive2
  • 2x E5620
  • Gigabit-Verbindung

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

Maschine B ist im Grunde im Leerlauf . Dies ist meine Erfahrung mit der Replikation unter MySQL 5.1. Die Replikation erfolgt mit einem Thread, und eine CPU wird maximal ausgelastet, während die anderen im Leerlauf sitzen.
Stefan Lasiewski

Machst du Backups vom Slave?
Mike

@ stefan-lasiewski Um es klar zu sagen, das ist MySQL 5.5, aber ja. Es ist Single-Threaded und sehr frustrierend
Nick

@Mike Ja, ebenso wie schwere Anfragen, die den ganzen Tag über viele Minuten dauern. Die Replikation wird auf ca. 100 Sekunden verlangsamt und es dauert eine Weile, bis sie wieder verfügbar ist. Der Dienst, der diese Abfragen ausführt, führt eine Abfrage aus, wartet darauf, dass sie aufholt, und führt dann eine weitere Abfrage aus, wartet usw. Wenn wir die Replikation beschleunigen können, können wir die Häufigkeit erhöhen, mit der diese Abfragen ausgeführt werden
Nick

1
@ stefan-lasiewski Ja - Wenn nichts die Replikation stoppt, wird sie offensichtlich nicht zurückbleiben. Das Hauptproblem besteht darin, dass die Replikationsgeschwindigkeit ein Engpass bei der Erhöhung der Schreibgeschwindigkeiten auf dem Master ist. Wenn es 3,3s dauert, um 1s aufzuholen, bedeutet dies, dass die Replikation 4,3s von Daten in 3,3s schreibt oder nur mit 130% der Geschwindigkeit der eingehenden Daten replizieren kann. Ich versuche, mindestens doppelt zu schreiben Laden Sie auf diesem Server.
Nick

Antworten:


4

Wow, Sie haben für dieses Problem einige schrecklich bullige Hardware. Es gibt nicht viel mehr, was die Hardware angeht, mit Ausnahme eines Upgrades auf Sandy / Ivy Bridge-CPUs für eine 20-50% bessere Leistung bei Btree-Suchvorgängen usw.

Bitte beachten Sie, dass meine Stärke Innodb ist, also gehe ich zu

  1. Ignorieren Sie, dass Sie myisam sind und tun Sie, als würde es keinen Unterschied machen.
  2. Angenommen, dieses Problem ist ausreichend, um Sie zum Upgrade zu bewegen. Ja, es ist ein Upgrade.

Innodb kann dabei helfen, den gesamten Speicher auszunutzen, indem diese Zeilen, auf die häufig zugegriffen wird, in seinem Pufferpool gespeichert werden. Sie können es so einstellen, dass es so groß ist, wie Sie möchten (etwa 80% des Speichers), und neue Lese- / Schreibvorgänge verbleiben im Speicher, bis sie auf die Festplatte verschoben werden müssen, um mehr Platz für die zuletzt aufgerufenen Daten zu schaffen. Im Speicher ist eine Größenordnung schneller als Ihre FusionIOs.

Es gibt viele weitere Innodb-Funktionen wie adaptive Hashes, Auto-Inc-Sperrmechanismen usw., die für Ihre Umgebung von Vorteil sein können. Sie kennen Ihre Daten jedoch besser als ich.

In der Welt von innodb besteht eine gute kurzfristige Lösung darin, Ihren Slave zu optimieren. Brauchen Sie wirklich jeden Index für Ihren Slave, den Sie für Ihren Master haben? Indizes sind eine Kugel und eine Kette von Einfügungen / Aktualisierungen / Löschungen, AUCH bei Fusion-IO-Karten. IOPS ist hier nicht alles. Sandy / Ivy-Bridge-Procs haben einen viel besseren Speicherdurchsatz und eine bessere Rechenleistung - sie können einen großen Unterschied zu den Westmeres machen, die Sie jetzt haben. (Abbildung 20-50% insgesamt). Entfernen Sie alle nicht benötigten Indizes auf dem Slave!

Zweitens, und dies gilt mit ziemlicher Sicherheit nur für innodb, kann mk-prefetch wissen, welche Aktualisierungen vorliegen und bevor der Slave sie schreibt. Dies ermöglicht mk-prefetch, zuerst eine Leseabfrage auszuführen, wodurch die Daten gezwungen werden, sich zu dem Zeitpunkt im Speicher zu befinden, zu dem die einzelne Replikation die Schreibabfrage ausführt. Dies bedeutet, dass sich die Daten im Speicher und nicht in fusionIO befinden, was eine schnelle Leistungssteigerung von einer Größenordnung darstellt. Das macht einen RIESIGEN Unterschied, mehr als man erwarten könnte. Viele Unternehmen nutzen dies als dauerhafte Lösung. Weitere Informationen finden Sie im Percona Toolkit .

Drittens, und vor allem, wenn Sie ein Upgrade auf Innodb durchgeführt haben, sollten Sie Tokutek auf jeden Fall ausprobieren. Diese Jungs haben ein paar unglaublich tolle Sachen, die die Leistung von Innodb beim Schreiben / Aktualisieren / Löschen um ein Vielfaches übertreffen. Sie kündigen eine verbesserte Replikationsgeschwindigkeit als einen der Hauptvorteile an , und Sie können anhand ihrer Benchmarks erkennen, warum Fusions crazy IOPS Ihnen bei Btrees immer noch nicht weiterhilft . (Anmerkung: Nicht unabhängig von mir verifiziert.) Sie verwenden einen Drop-In-Ersatz für einen Btree-Index, der viele der algorithmischen Geschwindigkeitsbeschränkungen von Btree-Indizes verbessert, obwohl er schrecklich komplexer ist.

Ich bin gerade dabei, eine Übernahme von Tokutek in Betracht zu ziehen. Wenn sie so viel Schreibgeschwindigkeit freigeben, kann ich mehr Indizes hinzufügen. Da sie die Daten und Indizes mit so hervorragenden Verhältnissen komprimieren (25x zitieren sie), zahlen Sie nicht einmal einen (Leistungs-, Wartungs-) Preis für erhöhte Daten. Sie zahlen ($) für ihren Motor, 2500 $ / Jahr pro vorkomprimiertem GB, IIRC. Sie haben Rabatte, wenn Sie die Daten replizieren lassen, aber Sie können Tokutek auch einfach auf Ihrem Slave installieren und Ihren Master so lassen, wie er ist. Informieren Sie sich über die technischen Details in der MIT Algoritms Open Courseware-Vorlesung . Alternativ haben sie jede Menge technisches Material in ihrem Blog und regelmäßige Whitepapers für diejenigen, die nicht 1:20 Zeit haben, sich das Video anzuschauen. Ich glaube, dieses Video gibt auch die Big-O-Formel für die Schnelligkeit der Lesevorgänge an. Ich habezu vermuten, dass die Lesevorgänge langsamer sind (es gibt immer einen Kompromiss!), aber die Formel ist zu komplex, als dass ich abschätzen könnte, wie viel. Sie behaupten, es sei ungefähr dasselbe, aber ich würde lieber die Mathematik verstehen (nicht wahrscheinlich!). Möglicherweise sind Sie in einer besseren Situation, dies zu entdecken, als ich.

Ps Ich bin nicht mit Tokutek verbunden, ich habe ihr Produkt nie ausgeführt und sie wissen nicht einmal, dass ich sie ansehe.

Update :

Ich sehe, dass Sie auf dieser Seite noch einige andere Fragen haben und ich dachte, ich würde einspringen:

Erstens funktioniert das Vorabrufen von Sklaven mit ziemlicher Sicherheit nicht für myisam, es sei denn, Sie haben eine außergewöhnliche Umgebung. Dies liegt hauptsächlich daran, dass beim Prefetching genau die Tabellen gesperrt werden, in die Sie schreiben möchten, oder dass der Slave-Thread die Tabelle gesperrt hat, die der Pre-Fetch-Daemon benötigt. Wenn Ihre Tabellen für die Replikation sehr ausgewogen sind und verschiedene Tabellen im Round-Robin-Verfahren beschrieben werden, funktioniert dies möglicherweise. Beachten Sie jedoch, dass dies sehr theoretisch ist. Das Buch "High Performance Mysql" enthält weitere Informationen im Abschnitt "Replikationsprobleme".

Zweitens, vermutlich hat Ihr Slave eine Last von 1.0-1.5. Sie kann höher sein, wenn Sie andere Prozesse oder Abfragen ausführen, aber eine Grundlinie von 1.0 haben. Dies bedeutet, dass Sie wahrscheinlich CPU-gebunden sind, was wahrscheinlich mit Ihrem FusionIO an Bord ist. Wie ich bereits erwähnte, wird Sandy / Ivy Bridge ein bisschen mehr Schwung geben, aber wahrscheinlich nicht genug, um Sie mit minimaler Verzögerung durch die raueren Zeiten zu bringen. Wenn die Last auf diesem Slave hauptsächlich nur schreibgeschützt ist (dh nicht viele Lesevorgänge), verbringt Ihre CPU mit ziemlicher Sicherheit Zeit damit, Positionen für das Einfügen / Löschen von Bäumen zu berechnen. Dies sollte meinen obigen Punkt zum Entfernen nicht kritischer Indizes verstärken - Sie können sie später jederzeit wieder hinzufügen. Das Deaktivieren von Hyperthreading funktioniert nicht, mehr CPU ist nicht Ihr Feind. Wenn Sie mehr als 32 GB RAM haben, beispielsweise 64 GB, müssen Sie sich um die RAM-Verteilung kümmern, aber auch dann sind die Symptome unterschiedlich.

Schließlich und vor allem (überspringen Sie diesen Teil nicht;)) gehe ich davon aus, dass Sie jetzt RBR (zeilenbasierte Replikation) ausführen, weil Sie eine nicht triviale Leistungssteigerung erwähnt haben, als Sie ebenfalls gewechselt haben. Es kann jedoch eine Möglichkeit geben, hier noch mehr Leistung zu erzielen. Der MySQL-Fehler 53375 kann auftreten, wenn Tabellen ohne Primärschlüssel repliziert werden. Der Slave ist im Grunde nicht schlau genug, etwas anderes als einen Primärschlüssel zu verwenden. Daher zwingt das Fehlen eines solchen Schlüssels den Replikationsthread, bei jedem Update einen vollständigen Tabellenscan durchzuführen. Ein Fix fügt einfach einen gutartigen, selbstinkrementierenden Ersatz-Primärschlüssel hinzu. Ich würde dies nur tun, wenn die Tabelle groß wäre (z. B. mehrere Zehntausend Zeilen oder größer). Dies geht natürlich zu Lasten eines anderen Indexes auf dem Tisch, der den Preis, den Sie in der CPU zahlen, erhöht. Beachten Sie, dass es nur sehr wenige theoretische Argumente dafür gibt, da InnoDB ein Argument hinter den Kulissen hinzufügt, wenn Sie dies nicht tun. Das Phantom ist jedoch keine nützliche Abwehr gegen 53375. Wolfram kann dieses Problem ebenfalls lösen, aber Sie müssen bei der Verwendung von Wolfram sicherstellen, dass Ihre Kodierung korrekt ist. Das letzte Mal, als ich damit gespielt habe, ist es fürchterlich abgestorben, wenn eine Nicht-UTF8-Zeichenfolge repliziert werden musste. Das ist ungefähr die Zeit, in der ich es aufgegeben habe.


Vielen Dank für Ihre Zeit! Ich freue mich sehr über die Informationen, die Sie hier gegeben haben. Der Wechsel zu InnoDB war etwas, über das wir schon seit einiger Zeit nachgedacht hatten, hauptsächlich wegen der Vorteile des Sperrens auf Zeilenebene. Dies gibt mir einige Denkanstöße. Danke noch einmal.
Nick

Wow, das ist eine wirklich brillante MySQL-Analyse :)
Kevin

4

Keine Antwort, aber Sie können Wolfram-Replikatoren und deren kommerzielle Produkte für mehr Flexibilität in Betracht ziehen . Ist es eine 100% ige CPU-Auslastung auf einem einzelnen Kern, die den Engpass darstellt?


Vielen Dank! Das ist eine interessante Lösung, obwohl ich ein wenig zögerlich bin, Software von Drittanbietern in MySQL zu integrieren. In den Dokumenten heißt es: "Es ist kein Upgrade erforderlich, um auf zukünftige MySQL-Versionen zu warten, oder es muss auf nicht getestete Alternativen migriert werden." Haben Sie Erfahrung mit Tungsten Replicator?
Nick

Nein, wissen Sie einfach, dass seriöser MySQL-Ökosystem-Mitarbeiter für sie arbeitet [ datacharmer.blogspot.com ]. Was ist mit dem Engpass? Sind Sie sicher, dass es sich um eine Single-Core-Last handelt, die den begrenzenden Faktor darstellt?
pQd

Danke für die Information. RE: der limitierende Faktor, nein, ich bin mir überhaupt nicht sicher. Ich glaube nicht, dass es sich um E / A handelt, da iostat meldet, dass das Fusion ioDrive Schreibvorgänge mit <10 MB / s ausführt. Ich bin mir ziemlich sicher, dass das Gerät weitaus mehr kann. Auf der anderen Seite gibt es immer 1 und zeitweise 1 zusätzlichen Kern, der zu 100% gekoppelt ist, während die anderen im Leerlauf sind. Was ist mit dem Deaktivieren von Hyper-Threading?
Nick

@ Nick - Entschuldigung, ich kann nicht über Hyper-Threading beraten. Aber versuchen Sie ... auch - versuchen Sie, Munin oder Cacti mit MySQL-Vorlagen zu installieren, und werfen Sie einen genaueren Blick darauf, was los ist.
pQd

Schauen Sie sich diesen Beitrag von Continuent an: scale-out-blog.blogspot.ca/2011/10/… Quote: "Insgesamt können wir mit Sicherheit sagen, dass die native Replikation mit einem Thread im E / A-Bereich wahrscheinlich nicht funktioniert Fall, ohne zu einer Kombination von SSDs und / oder Slave-Pre-Fetch zu gehen. "
HTTP500

2

Wenn Sie also Backups auf dem Slave durchführen und Myiasm-Tabellen verwenden, sperren Sie die Tabellen, um Backups zu erstellen und Beschädigungen zu vermeiden. Die Replikation funktioniert also erst, wenn die Sicherung abgeschlossen ist. Dann holt sie auf.


Absolut. Wir sperren regelmäßig Tabellen für Sicherungen oder lange Abfragen, aber das Problem liegt in der Geschwindigkeit der Replikation, sobald der E / A-Thread fortgesetzt wird. Ich schätze, dass die Replikation nur mit 130% der Geschwindigkeit der eingehenden Daten erfolgt, was die weitere Skalierbarkeit dieses Setups einschränkt, sofern die Replikationsgeschwindigkeit nicht verbessert werden kann. Ist das sinnvoll?
Nick
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.