MySQL-Clustervarianten gibt es einige, aber erst ein Team aus Coderships Galera und dem Schrittmacher Pacemaker macht die Datenbank zu einem sicheren Verbund mit den Leistungsreserven beliebig vieler Primary-Knoten. Dafür ist jedoch derzeit noch ein wenig Handarbeit notwendig.
Eine große MySQL-Datenbank auf perfekt koordinierte und skalierbare Hochverfügbarkeit zu trimmen erfordert Einsatzbereitschaft und Durchhaltevermögen. Auf den Lösungswegen, die MySQL nur um HA-Features erweitern, lauern viele Stromschnellen, selbst einfache Skalierbarkeit ist nur schwer zu erreichen.
Galeere am Horizont
Doch eine Lösung scheint in Sicht, seit die Firma Codership [1] mit ihrer Software Galera [2] ein neues Boot ins Rennen schickt: Galera erweitert MySQL um ein Plugin, das sich um die Replikation der Daten eines Clusters kümmert. Dabei bleibt jeder einzelne Clusterknoten eine normale MySQL-Instanz, die Lese- und Schreibzugriffe selbst abwickelt.
Dieser Artikel beschäftigt sich mit der Frage, wie sich ein solches Gespann aus Galera-Knoten sinnvoll in den Clustermanager Pacemaker [3] integrieren lässt. Um zu verstehen, was Galera so revolutionär erscheinen lässt und wieso es sinnvoll ist, den eigentlich autonomen Cluster aus Galera-Knoten um einen Schrittmacher zu ergänzen, ist ein kleiner Ausflug in die Grundlagen der Hochverfügbarkeit und Skalierung von MySQL nötig.
MySQL ist ein hervorragendes Beispiel für den Wildwuchs an HA-Lösungen, der in den letzten Jahren vielerorts entstand, wenn Applikationen Hochverfügbarkeits-Funktionen fehlen. Ursprünglich bot die Datenbank überhaupt keine Möglichkeit, einzelne Instanzen in einem Rechnerverbund miteinander kommunizieren zu lassen. Häufig betreiben Admins deshalb MySQL-Deployments, die das Problem mit DRBD oder einem SAN-Storage auf Block-Level des Linux-Kernels zu umgehen trachten.
Die Idee hinter so einem Setup ist einfach: Wenn MySQL auf beiden Knoten eines 2-Node-Clusters jeweils die gleichen Daten zur Verfügung hat, lässt sich »mysqld« auf jedem Knoten starten, ohne dass Clients einen Unterschied bemerken. DRBD oder das genutzte SAN kümmern sich um die Replikation der Daten, der eigentliche Datenbankordner »/var/lib/mysql« ist nur ein Mountpoint.
Diese Art des MySQL-Clusterings hat aber zwei große Nachteile: »mysqld« kann jeweils nur auf einem der beiden Knoten laufen, weil sonst konkurrierender Zugriff auf die MySQL-Daten stattfände. Wer dafür zwei schnelle Server einsetzt, verdammt einen von beiden also immer dazu, sich zu langweilen.
Der zweite Pferdefuß ist die Tatsache, dass nach einem Failover der »mysqld« auf dem verbliebenen Knoten zum Beispiel bei Inno DB erst mal seinen Recovery-Prozess durchläuft. War zum Crash-Zeitpunkt das Binlog etwas größer, dann wird dieser Vorgang einige Zeit in Anspruch nehmen, bis zu 20 Minuten sind durchaus möglich. Vom viel zitierten “Instant Failover” kann da keine Rede sein.
Nicht transaktionssicher
Auch andere Cluster-Lösungen für MySQL stehen kaum besser da. Der mittlerweile vorhandene Master-Slave-Modus erlaubt zwar das Skalieren von MySQL, ist aber nicht transaktionssicher. Denn wenn ein Slave-Knoten nach dem Ausfall des Master-Hosts zum neuen Master wird, hat er unter Umständen noch nicht alle Updates von diesem empfangen.
Es bliebe als Lösung des Problems noch der von MySQL als eigenständiges Produkt vertriebene MySQL Cluster [4]. Doch auch der ist keine wirklich geclusterte Datenbank, sondern eher ein großer Key-Value-Store, der mit komplexen SQL-Queries nicht richtig umgehen kann.
Genau an dieser Stelle setzt Galera an: Die Entwickler von Codership wollten eine MySQL-Cluster-Lösung schaffen, die einerseits nicht auf eine bestimmte Anzahl von Knoten beschränkt ist, gleichzeitig aber dafür sorgt, dass jeder Knoten innerhalb des Verbunds als vollwertige MySQL-Datenbank fungiert, also auch inklusive Lese- und Schreibzugriff.
Galera legt ab
Ein Galera-Cluster besteht aus beliebig vielen Servern, auf denen ein normaler »mysqld« -Dienst läuft. Alle MySQL-Instanzen des Clusters kommunizieren miteinander und stellen so sicher, dass jeder der Knoten stets die neuesten Daten hält. In Kombination mit einem Loadbalancer wirkt das Konstrukt nach außen wie eine einzige kompakte Datenbank – dass im Hintergrund tatsächlich eine größere Anzahl arbeitet, merkt die Clientsoftware nicht.
Möglich wird das Setup durch die von Codership entwickelte Writeset Replication, die Veränderungen in so genannte Writesets zusammenfasst und dann unter den Knoten des Clusters verteilt [5]. Streng genommen ist Galera also lediglich ein Werkzeug, das die Funktionen des Wsrep-API nutzt, um die Multi-Master-Replikation zu gewährleisten.
Wenn sich MySQL über den Umweg von Galera selbst um die Hochverfügbarkeit seiner Daten kümmert, scheint Pacemaker als klassischer Clustermanager auf den ersten Blick eigentlich unnötig. Doch der Schrittmacher hilft, indem er alle Galera-Instanzen im Cluster überwacht. Ist außerdem Stonith adäquat eingerichtet, dann hat er auch die nötige Autorität, um mögliche verdächtige Knoten aus dem Verbund zu werfen und so größeren Schaden zu verhindern.
Außerdem kann sich der Schrittmacher bei Clustern mit mehr als zwei Knoten auch um die zentrale IP-Adresse kümmern, über die vorübergehend aus dem Verbund geflogene Rechner wieder Kontakt mit den anderen Knoten aufnehmen. Pacemaker ist ohnehin spätestens für die Loadbalancer-Software notwendig – es schadet sicher nicht, dieser auch die Aufsicht über MySQL und Galera zu übertragen.
Vorarbeit
Hat der Admin seine Server wie im Kasten “Vorbereitungen für Galera und Pacemaker” grundlegend konfiguriert, können die vorhandenen Clusterknoten bereits miteinander reden: Im Erfolgsfall zeigt der Befehl »mysql -e ” SHOW STATUS like ‘%wsrep%’;”« auf jedem der Knoten, dass die Galera-Replikation aktiv ist und funktioniert (Abbildung 1).
Vorbereitungen für Galera und Pacemaker
Die sehr detailreiche Konfiguration und Installation von Galera und Pacemaker erläutert ein Artikel im ADMIN-Magazin [6]. Allerdings ist für Galera ein umfassendes Patch nötig, das MySQL um das »wsrep« -API erweitert. Wer die Galeere genauer betrachten will, findet auf der Website des Projekts [7] fertige Pakete mit »wsrep« -Funktionalität für die gängigsten Distributionen – die Debian-Variante der Pakete lässt sich etwa als Ersatz für Debians Standard-MySQL-Pakete installieren. Zusätzlich ist dann das »galera« -Paket notwendig, das Admins aber ebenfalls auf der Codership-Seite [2] finden.
Alternativ bieten sich die Pakete für Perconas Xtradbcluster an. Diese stehen auf der Website von Percona [8] als freier Download zur Verfügung, auch bei diesen Paketen ist die »wsrep« -Funktionalität bereits ab Werk vorhanden. Ebenso wie Codership bringt auch Percona ein fertiges Paket für Galera, das sich nach dem Hinzufügen des Repository zur System-Konfiguration einfach über die Paketverwaltung installieren lässt.
Schrittmacher und Loadbalancer
Für Pacemaker sind dagegen keine beschwerlichen Klimmzüge notwendig, denn den Clustermanager in paketierter Form samt Abhängigkeiten halten fast alle Distributionen vor. Meist genügt es bereits, das Paket »pacemaker« zu installieren, um sich den gesamten Linux-HA-Stack in einem Rutsch aufs System zu holen. Eine grundlegende Einführung in die Konfiguration von Pacemaker gibt [9].
Fehlt nur noch der im Artikel ebenfalls erwähnte Loadbalancer »glb« : Der ist erst kürzlich in einer aktualisierten Version erschienen und steht folglich für die meisten Distributionen noch nicht als Paket bereit. Der Autor dieses Artikels bietet aber unter [10] kompilierte Pakete für Debian GNU/Linux 6.0 sowie Ubuntu 12.04 an, die Admins per »wget« laden und mittels »dpkg« installieren können. Für andere Distributionen ist derzeit noch manuelles Übersetzen angesagt.

Abbildung 1: Bevor die Arbeit am Cluster losgeht, muss der Admin Galera konfigurieren, damit sich alle Clusterknoten gegenseitig sehen.
Pacemaker sollte – in Kombination mit Corosync – so eingestellt sein, dass »crm_mon -rf« die Anwesenheit aller Knoten im Cluster bescheinigt (Abbildung 2). Sind all diese Voraussetzungen erfüllt, steht dem Setup aus Galera auf der einen Seite und Pacemaker auf der anderen eigentlich nichts mehr im Wege.

Abbildung 2: Ein Blick in Pacemakers »crm_mon« beweist die erfolgreiche Konfiguration. MySQL läuft auf allen vier Clusterknoten.
Aber die Entwickler von Codership haben bei der Galera-Entwicklung eine aus heutiger Sicht unglückliche Entscheidung getroffen. Weil sie für ihr Produkt sicherstellen mussten, dass alle Knoten des Clusters über ein standardisiertes Protokoll miteinander kommunizieren, erfanden sie das Rad neu und implementierten den kompletten Communication Layer selbst. Sinnvoller wäre es wohl gewesen, die vorhandene Corosync-Umgebung statt eines Eigenbaus zu verwenden.
Wer zuerst kommt …
Weil Codership zudem die Kommunikation innerhalb des Clusters nur halbherzig umsetzte, kommt Galera mit einer für Clusterumgebungen ungewöhnlichen Idee daher: Innerhalb des Galera-Clusters muss der Admin den ersten Knoten mit dem Parameter »–wsrep_cluster_address =gcomm://« starten. Für Galera ist dies das Zeichen, dass dieser Knoten einen neuen Galera-Cluster startet, der dann automatisch die »Primary« -Rolle erhält.
Allen anderen Knoten gibt die Software identische Parameter mit auf den Weg, wobei jetzt als Adresse hinter »gcomm://« die IP-Adresse des Knotens steht, der schon läuft. Kommt ein Knoten über diese IP-Adresse in den Cluster, nehmen die bereits vorhandenen Nodes eigenständig die Verbindung auf. Anders als bei Corosync ist es bei Galera nicht möglich, die Knoten in beliebiger Reihenfolge zu starten, weil diese die Cluster-Mitgliedschaft untereinander aushandeln (Abbildungen 3 und 4).

Abbildung 3: Eine MySQL-Verbindung über die Service-IP »10.43.0.120«. Auf welchem der vier Knoten diese Verbindung terminiert, sieht der Client nicht.

Abbildung 4: Auf drei Knoten läuft die Galera-Datenbank mit Gcomm-Adresse, der Knoten »camilla« war hingegen der erste Knoten dieses Galera-Clusters.
Hinzu kommt ein weiteres Problem: Galera bietet derzeit keine Möglichkeit, per Konfigurationsdatei die IP-Adressen aller Knoten anzugeben, die am Cluster beteiligt sind. In der Galera-Konfiguration lässt sich eine solche Liste nur für das Helferskript »mysqld_safe« angeben. Das Skript tut nichts anderes, als »mysqld« neu zu starten, wenn der Prozess sich selbst beendet – beispielsweise reagiert »mysqld« in einem Galera-Setup, wenn es die per »–wsrep_cluster_address=« -Parameter angegebene Adresse nicht erreichen kann. »mysqld_safe« startet gegebenenfalls also »mysqld« so oft neu, bis es alle Server-Einträge durch hat und als Fallback dann ein neuer Cluster mit einem leeren »–wsrep_cluster_address=« -Parameter folgt.
MySQL gegen Pacemaker
Der Haken daran: »mysqld_safe« pfuscht durch die Neustarts Pacemaker und seiner Monitoring-Funktion ins Handwerk. Im Netz finden sich zwar unzählige Anleitungen, mit deren Hilfe normale MySQL-Server mit »mysqld_safe« arbeiten, zu empfehlen ist das im Cluster-Kontext aber keineswegs. Auf jeden Fall wirkt sich dieser Umstand auf die Integration in Pacemaker aus. Denn der Schrittmacher muss wissen, welcher Rechner innerhalb eines Clusters gerade der gestartete Clusterknoten ist, damit er entsprechend reagieren kann.
Normalerweise scheint die Sache klar: Weil auf jedem Knoten des Clusters ein »mysqld« -Dienst läuft, hat der Admin MySQL einmal als Ressource zu definieren und danach mittels einer »clone« -Anweisung Cluster-weit zu starten. Klon-Ressourcen sorgen in Pacemaker dafür, dass eine Ressource mit identischen Parametern auf allen Knoten läuft. Einen Resource Agent, der sich um MySQL kümmert, gibt es bereits ohnehin, nämlich »ocf:heartbeat:mysql« .
Ein Agenten-Patch für die Galera-Eigenheiten
Der Pferdefuß bei dieser Variante: Der normale Resource Agent für MySQL kennt die Galera-Eigenheiten nicht, weiß also auch nicht, dass der erste Knoten im Verbund mit anderen Parametern zu starten ist als alle anderen Knoten. Die Probleme löst eine vom Autor dieses Artikels gepatchte Version des MySQL-Agent, sie ermöglicht das Galera-Setup in Pacemaker ([11], Abbildung 5).

Abbildung 5: Der Abschnitt unter »Galera Magic« im Code sorgt dafür, dass der Resource-Agent MySQL als Masterknoten startet, wenn die Ressource sonst nirgends läuft.
Mit dem gepatchten Agenten lässt sich ein Galera-Setup – wie zuvor erklärt – tatsächlich als Klon-Ressource in Pacemaker betreiben. Der Agent überprüft dabei zunächst, ob eine Instanz des Klons schon auf einem Clusterknoten läuft. Instances sind im Pacemaker-Jargon die einzelnen Ressourcen auf den Clusterknoten, die zu einer Cluster-weiten Klon-Anweisung gehören. Damit sie eindeutig identifizierbar sind, erhalten sie auch eindeutige Nummern.
Auf den imaginären Clusterknoten Alice, Bob und Charlie würden beispielsweise die Instanzen »p_mysql:0« , »p_mysql:1« und »p_mysql:2« gestartet, die zum Klon »cl_mysql« gehören. Stellt der gepatchte Agent fest, dass noch keine Instanz des Klons läuft, erklärt er die Instanz mit der laufenden Nummer »« zum künftigen ersten »Primary« -Knoten und startet sie mit dem »–wsrep_cluster_address=« -Parameter ohne Adresse.
Location Constraint
Mit an Bord bei dieser Konfiguration ist auch eine dedizierte virtuelle IP-Adresse. Weil alle anderen Galera-Instanzen eine IP für die Verbindung brauchen, sorgt der Agent dafür, dass die in der Konfiguration der Ressource für »mysqld« angegebene IP-Adresse tatsächlich auch auf dem Knoten läuft, der die Instanz 0 des Klons startet.
Nach erfolgreichem Start dieser Instanz löscht der Agent den so genannten Location Constraint wieder, der die IP fix an den Host bindet, auf dem die erste Galera-Instanz läuft. Denn im weiteren Verlauf gilt: Solange der Galera-Cluster noch funktionstüchtig ist, darf kein Knoten mehr mit dem »–wsrep_cluster _address=gcomm://« -Parameter starten, weil sich sonst ein konkurrierender Cluster bilden würde. Fällt der Knoten aus, auf dem die ursprüngliche Instanz 0 läuft, startet Pacemaker die IP sofort auf einem anderen Galera-Knoten.
Agenten installieren
Der modifizierte Agent für MySQL wandert mit »wget -O« gleich an den richtigen Platz im Dateisystem: »/usr/lib/ocf/resource.d/heartbeat/mysql-galera« . Der Schritt ist auf allen Clusterknoten nötig, genauso wie das anschließende Kommando »chmod a+x /usr/lib/ocf/resource.d/heartbeat/mysql-galera« , das den Agenten ausführbar macht. Anschließend sollte ein »crm ra info ocf:heartbeat: mysql-galera« auf der Kommandozeile den Hilfetext des Agenten auf den Bildschirm holen.
Wichtig ist auch, dass der Admin alle eventuell vorhandenen Einträge für MySQL aus den Runlevels für die Clusterknoten entfernt. Denn sobald Pacemaker die Kontrolle übernimmt, darf ihm das System nicht mehr in die Quere kommen. Auf Debian- und Ubuntu-Rechnern geht das mit »update-rc.d -f mysql remove« . Läuft indes Galera bereits, dann ist es vermutlich von »mysqld_safe« gestartet. Es empfiehlt sich, alle laufenden MySQL-Instanzen vor der Arbeit am Cluster zu beenden und Pacemaker das Feld komplett zu überlassen.
Galera integrieren und Loadbalancer vorspannen
Der vorletzte Schritt für das passende Galera-Setup besteht darin, den Galera-Agent entsprechend einzusetzen. Eine zusammenhängende Konfiguration zeigt Listing 1, das IP-Adresse, Galera-Ressource und die zugehörige »clone« -Anweisung enthält.
Listing 1
IP-Adresse und Galera-Ressource
01 primitive p_galera_ip ocf:heartbeat:IPaddr2 \ 02 params cidr_netmask="255.255.255.0" ip="10.43.0.130" iflabel="galera" 03 primitive p_mysql ocf:heartbeat:mysql-galera \ 04 params galera_port="4567" galera_cluster_address="10.43.0.130" binary="mysqld" \ 05 config="/etc/mysql/my.cnf" datadir="/var/lib/mysql" socket="/var/run/mysqld/mysqld.sock" \ 06 pid="/var/run/mysqld/mysqld.pid" additional_parameters="--plugin-dir=/usr/lib/mysql/plugin \ 07 --user=mysql --log-error=/var/lib/mysql/galera.err" op monitor interval="30s" timeout="20s" 08 clone cl_mysql p_mysql meta ordered="true"
So ein typischer Galera-Cluster bringt in Sachen Skalierbarkeit aber nichts, wenn die Clients nicht auch alle verfügbaren Galera-Instanzen tatsächlich nutzen. Leider bieten die meisten Clients nicht die Möglichkeit, mehrere IP-Adressen für Datenbankverbindungen anzugeben, aus denen die Applikation sich eine zufällige holt. DNS-basierte Lösungen sind heikel, weil sie auf den Ausfall eines einzelnen Galera-Knotens nicht adäquat reagieren können und Benutzer gegebenenfalls zu ausgefallenen Knoten führen. Ein Loadbalancer muss her.
Codership selbst stellt für Galera einen Loadbalancer zur Verfügung, den Galera Load Balancer (GLB), ein Abkömmling des bekannteren Pen [12]. Ist der GLB erst einmal installiert, wird die restliche Arbeit ein Kinderspiel. Zwar existiert für GLB ab Werk kein OCF-Agent, der den Loadbalancer ordentlich in Pacemaker integriert – doch der Autor dieses Artikels stellt einen für GLB bereit [13], den der Admin wie den Galera-Agenten auf allen Clusterknoten installiert. Listing 2 enthält die klassische Konfiguration für eine GLB-Ressource in Kombination mit einer weiteren Service-IP als Verbindungspunkt für Datenbank-Clients.
Listing 2
Ressourcen-Konfiguration für GLB
01 primitive p_ip ocf:heartbeat:IPaddr2 \ 02 params ip="10.43.0.120" cidr_netmask="255.255.255.0" iflabel="mysql" \ 03 op monitor interval="20s" timeout="10s" 04 primitive p_glbd ocf:heartbeat:glbd \ 05 params control_address="10.43.0.120:4444" control_socket="/var/run/glbd/glbd.fifo" \ 06 destination_servers="10.43.0.121:3306:10 10.43.0.122:3306:10 10.43.0.123:3306:10 10.43.0.124:3306:10" listen_address="10.43.0.120:3306" \ 07 op monitor interval="20s" timeout="20s" 08 group g_services p_ip p_glbd 09 order o_glbd_after_mysql inf: cl_mysql:start g_services:start
Kurz vor dem Ziel
Noch ist nicht alles Gold, was bei Galera glänzt – wünschenswert ist beispielsweise, dass die Funktionen des im Artikel vorgestellten Galera-Resource-Agenten direkten Einzug in den MySQL-Agent halten und Teil des »resource-agents« -Projekts werden.
Auch mit Blick auf die unterstützten Features bleibt genug Arbeit für die Entwickler: In der getesteten Version funktionierte der Resource-Agent für Galera nur dann zufriedenstellend, wenn auf jedem Knoten des Pacemaker-Clusters auch tatsächlich eine Galera-Instanz lief. Dann aber kann sich Pacemaker selbst um das Quorum kümmern und den Cluster im Falle eines Falles abschalten.
Wer hingegen per »location« -Constraint den Betrieb von Galera auf einzelnen Knoten deaktiviert, muss irgendwie dafür sorgen, dass sich der Resource-Agent selbstständig um die Überwachung des Quorums für Galera kümmert. Diese Funktion unterstützt er im Augenblick aber nicht.
Insbesondere Admins, die sich in naher Zukunft mit dem Aufbau einer Cloud-Infrastruktur beschäftigen, sei dennoch Galera empfohlen. Richtig getaktet zeigt die Galeere ihre Stärken und liegt im Rennen um skalierbare MySQL-Datenbanken im Multi-Primary-Prinzip derzeit vorne. Es scheint nicht unwahrscheinlich, dass die Kombination mit Pacemaker früher oder später auch integraler Bestandteil von Cloudumgebungen wird.
Infos
- Codership: http://codership.com
- Galera: http://codership.com/content/using-galera-cluster
- Martin Loschwitz, “Dabeibleiben ist alles”: Linux-Magazin 05/12, S. 40
- MySQL Cluster: http://www.mysql.de/products/cluster/
- Experimenting with Writeset Replication: http://codership.blogspot.de/2009/01/experimenting-with-write-set.html
- Oliver Sennhauser, “Abgesichert”: ADMIN-Magazin 04/12, S. 88
- Galera-Pakete: http://codership.com/downloads/download-mysqlgalera
- Download von Perconas Xtradbcluster: http://www.percona.com/software/percona-xtradb-cluster
- Martin Loschwitz, “CLuster-Leitstand”: Admin-Magazin 04/11, S. 68
- GLB-Pakete für Debian: http://people.debian.org/~madkiss/lm/galera
- Agent für Galera: http://github.com/madkiss/resource-agents/tree/master/heartbeat/mysql-galera
- Pen: http://siag.nu/pen
- Resource-Agent für GLB: http://github.com/madkiss/resource-agents/tree/master/heartbeat/glbd






