Wie alle anderen Komponenten von IT-Setups auch müssen Datenbanken heute in die Breite skalieren. Für lesende Zugriffe ist das trivial, aber wie lassen sich MariaDB-Cluster so konstruieren, dass der schreibende Zugriff auf parallel laufende Instanzen möglich wird? Galera bietet die Lösung für dieses Problem.
Nichts bleibt wie es war – das ist nicht nur eine Erkenntnis des rheinischen Grundgesetzes, sondern in der IT auch der Normalzustand. Weil sich immer mehr Dienste ins Digitale verlagern, wachsen die Anforderungen an IT-Installationen kontinuierlich – und die Last, mit der diese es zu tun haben. In den vergangenen Jahren haben deshalb Konzepte für das Skalieren in die Breite kontinuierlich an Relevanz gewonnen. Logisch: Auch mit der potentesten CPU und absurden Mengen RAM stoßen einzelne Server irgendwann an die Grenzen dessen, was sie zu leisten imstande sind. Gut, wenn sich die Last stattdessen auf beliebig viele physische Knoten verteilen lässt. Weil praktisch jedes Setup der Gegenwart Datenbanken nutzt, gilt dieser Grundsatz natürlich auch für PostgreSQL, MariaDB undamp; Co.
Datenbanken skalierbar zu bauen, ist allerdings alles andere als trivial. Die Probleme gleichen jenen von Storage-Lösungen mit eingebauter Replikation wie etwa Ceph: Eine skalierte Datenbank muss einerseits sicherstellen, dass von Clients durchgeführte Writes sauber bei allen teilnehmenden Knoten ankommen, bevor der Client den Write als erfolgreich durchgeführt gemeldet bekommt. Sie muss andererseits resilient sein, damit nicht im Falle eines Hardware-Ausfalls unkontrolliert auf zwei nun disjunkte Partitionen eines einzelnen Clusters geschrieben wird. Das alles darf freilich nicht zulasten der Performance laufen: Ein Multi-Knoten-MariaDB nützt niemanden, wenn es für einzelne Commits eine gefühlte Ewigkeit benötigt.
Single-Master-Replikation ist simpel
Manchem Admin mag aus der Vergangenheit das Konzept der Single-Master-Replikation noch ein Begriff sein. MySQL und MariaDB beherrschen diese Technologie seit Jahren. Dabei fungiert ein einzelner MySQL-Server ("Master") als exklusives Ziel für alle Schreibvorgänge. Die machen in Datenbanken typischerweise allerdings gar nicht das Gros der Zugriffe aus – in aller Regel sind Datenbanken stark leselastig.
Nichts bleibt wie es war – das ist nicht nur eine Erkenntnis des rheinischen Grundgesetzes, sondern in der IT auch der Normalzustand. Weil sich immer mehr Dienste ins Digitale verlagern, wachsen die Anforderungen an IT-Installationen kontinuierlich – und die Last, mit der diese es zu tun haben. In den vergangenen Jahren haben deshalb Konzepte für das Skalieren in die Breite kontinuierlich an Relevanz gewonnen. Logisch: Auch mit der potentesten CPU und absurden Mengen RAM stoßen einzelne Server irgendwann an die Grenzen dessen, was sie zu leisten imstande sind. Gut, wenn sich die Last stattdessen auf beliebig viele physische Knoten verteilen lässt. Weil praktisch jedes Setup der Gegenwart Datenbanken nutzt, gilt dieser Grundsatz natürlich auch für PostgreSQL, MariaDB undamp; Co.
Datenbanken skalierbar zu bauen, ist allerdings alles andere als trivial. Die Probleme gleichen jenen von Storage-Lösungen mit eingebauter Replikation wie etwa Ceph: Eine skalierte Datenbank muss einerseits sicherstellen, dass von Clients durchgeführte Writes sauber bei allen teilnehmenden Knoten ankommen, bevor der Client den Write als erfolgreich durchgeführt gemeldet bekommt. Sie muss andererseits resilient sein, damit nicht im Falle eines Hardware-Ausfalls unkontrolliert auf zwei nun disjunkte Partitionen eines einzelnen Clusters geschrieben wird. Das alles darf freilich nicht zulasten der Performance laufen: Ein Multi-Knoten-MariaDB nützt niemanden, wenn es für einzelne Commits eine gefühlte Ewigkeit benötigt.
Single-Master-Replikation ist simpel
Manchem Admin mag aus der Vergangenheit das Konzept der Single-Master-Replikation noch ein Begriff sein. MySQL und MariaDB beherrschen diese Technologie seit Jahren. Dabei fungiert ein einzelner MySQL-Server ("Master") als exklusives Ziel für alle Schreibvorgänge. Die machen in Datenbanken typischerweise allerdings gar nicht das Gros der Zugriffe aus – in aller Regel sind Datenbanken stark leselastig.
Also stellen IT-Verantwortliche der Master-Instanz diverse Partnerinstanzen zur Seite, die nur lesenden Zugriff ermöglichen. Weil nur eine Instanz Schreibzugriff erlaubt, ergeben sich sämtliche der zuvor beschriebenen Probleme beim Skalieren in die Breite nicht. Im Gegenzug bietet der Ansatz aber auch keine befriedigende Lösung, sollte der Master-Server doch mal in Performanceprobleme kommen. Eine befriedigende Lösung in Sachen Hochverfügbarkeit ist der Single-Master-Ansatz mit Replikation außerdem nicht. Stürzt der Master-Server ab, schauen Clients mit ihren Schreibzugriffen zunächst in die Röhre. Admins behalfen sich in der Vergangenheit regelmäßig damit, Datenbanken als Ressource im HA-Clustermanager [1] Pacemaker zu betreiben.
Das allerdings kommt mit ganz eigenen Problemen daher, denn Pacemaker ist komplex und genießt nur bei wenigen Admins einen guten Ruf. Obendrein bedingt eine Datenbank als Ressource in Pacemaker immer auch replizierten Speicher, etwa in Form von DRBD. Fällt ein MySQL-Master aus, kümmert Pacemaker sich darum, dass der Dienst mitsamt seiner IP auf ein anderes System umzieht. Das allerdings kann dauern: Die Datenbank auf dem nun zuständigen Host muss nämlich erstmal durch einen Recovery-Prozess, um die Integrität der eigenen Daten nach dem Crash des Clusterpartners zu gewährleisten Und das kann im Fall von MariaDB mit InnoDB-Backend je nach Datenmenge eine ganze Weile dauern. Von "Instant Failover" kann dabei jedenfalls nicht die Rede sein.
Wie wir es also auch drehen und wenden: Hochverfügbarkeit auf der Datenbankebene und sinnvolles Skalieren in die Breite sind nur mit einem Datenbank-Cluster möglich, auf dessen einzelne Knoten sich schreibend zugreifen lässt. Für MariaDB und MySQL kommt an dieser Stelle Galera ins Spiel.
Erprobtes Galera
Galera ist keine ganz neue Lösung. Codership, die Firma hinter dem Produkt, entwickelt an der Software bereits seit über einem Jahrzehnt. Kontinuierlich haben seine Macher das Produkt in den vergangenen Jahren aber verbessert, und heute gilt Galera als feste Größe im Geschäft der skalierbaren Datenbanken. Bemerkenswert dabei ist, dass Galera keine eigene Datenbank implementiert. Es nutzt stattdessen die Plug-in-Schnittstelle von MySQL oder MariaDB.
Im Kern funktioniert das so: Jede Datenbank im Cluster nutzt das entsprechende Plug-in und erfährt über dessen Konfiguration, wer die anderen Knoten im Cluster sind. Jede Galera-Instanz kennt also alle anderen Cluster-Partner. Untereinander überwachen die Galera-Instanzen sich und jeder Schreibvorgang, den ein Client bei einer Instanz des Clusters deponiert, repliziert dieses automatisch zu allen anderen Instanzen. Die letzte Frage, die sich dabei noch stellt, ist, woher der Client weiß, mit welchen Datenbanken er kommunizieren kann. Das Problem zu lösen ist allerdings trivial, denn der Datenbankzugriff durch einen Loadbalancer hindurch gilt technisch längst als ein Standardverfahren. Und selbst der Einwand, ein Loadbalancer könnte eine Datenbank nicht zuverlässig auf ihre Funktionalität hin überwachen, greift nicht: Der Client merkt ja, falls ein Write nicht erfolgreich bei der Datenbank landet. Ihm kommt dann die Aufgabe zu, den Schreibvorgang zu wiederholen.
Beschäftigt der Admin sich mit Galera, begegnen ihm ein paar Begriffe immer wieder. Ein solcher Begriff ist die etwas sperrige Worthülse "wsrep", die hier einer genaueren Erklärung bedarf. Damit einhergeht die Frage, wie Galera eigentlich repliziert. Die moderne IT unterscheidet bekanntlich wenigstens zwischen asynchroner und synchroner Replikation. Dass es etwaige Mischformen gibt, bleibt an dieser Stelle unbeachtet. Der Unterschied zwischen asynchroner und synchroner Replikation ist immens – ganz konkret geht es nämlich um die Frage, wann ein Client die Bestätigung erhält, dass ein in der Datenbank beauftragter Schreibvorgang erfolgreich abgeschlossen ist.
Bei asynchroner Replikation genügt es üblicherweise, wenn das Zielsystem die zu schreibenden Daten in irgendeiner Art und Weise erhalten hat. Sie können dort dann noch im Netzwerkpuffer oder im RAM liegen und müssen nicht unbedingt erfolgreich auf dem Datenträger gelandet sein. Synchrone Replikation schreibt hingegen vor, dass der Schreibvorgang auf zumindest so vielen Zielsystemen erfolgreich auf den Datenträgern abgeschlossen worden sein muss, wie es die jeweilige Replikationsregel des Admins vorgibt.
Der Client kann also zuverlässig davon ausgehen, dass die Daten es auf mehreren Systemen auf die Platte geschafft haben. In verteilten Systemen ist das von großer Bedeutung: Schließlich wäre es auch denkbar, dass ein anderer Client gerade dieselbe Tabelle in der Datenbank bearbeitet. Geht nun etwas schief, wäre die Datenbank im schlechtesten Falle korrupt, weil zwei inkompatible Writes nicht richtig koordiniert und abgehandelt worden sind. Genau aus diesem Grund nutzen Datenbanken fast immer synchrone Replikation.
Replikation unter Galera
Auch das ist allerdings nicht ohne Nachteile. Ein großer Nachteil ist, dass Clients beim Schreiben in synchron replizierte Datenbanken warten müssen, bis sie das "Okay" für den Schreibvorgang von allen Instanzen erhalten. Je nach genutzter Netzwerktechnik spielt die anliegende Latenz hier eine große Rolle und macht die Datenbank praktisch unbenutzbar, weil extrem langsam. Genau hier kommt bei Galera "wsrep" ins Spiel. Es handelt sich um eine Abkürzung, die für "Write Stream Replication" steht und genauer beschreibt, wie Galera im Hintergrund die Replikation abwickelt. Ihren Ansatz nennen die Entwickler auch nicht "synchrone Replikation", sondern "virtuelle synchrone Replikation". Was im ersten Augenblick nach einer Gefahr für Daten klingt, hat aber einen schlauen technischen Hintergrund.
Galera betrachtet die eingehenden Daten nämlich einerseits als "Stream", den Clients bei den Galera-Instanzen abladen, und setzt andererseits auf ein Prinzip, das die Entwickler "zertifikatsbasierte Replikation" nennen. Das funktioniert so: Eine Galera-Instanz, die zu schreibende Daten enthält, leitet an ihre Cluster-Partner nicht nur die zu schreibenden Daten weiter – sondern legt diesen Daten auch eine Information zum aktuellen Zustand der Datenbank bei. Darunter fällt etwa die Information, auf welche Teile des Datensatzes gerade schreibender Zugriff passiert.
Anhand dieses Zertifikates kann die passive Cluster-Instanz also schließen, wie die Datenbank während der verschiedenen Phasen des Vorgangs ausgesehen hat. Der Clou: Das Zertifikat funktioniert im Grunde wie eine Art Journal bei Dateisystemen. Weil die Datenbank anhand der Zustandsinformation, die den Daten beiliegt, den erfolgreichen Schreibzugriff garantieren kann, muss sie den Client nicht warten lassen – sondern kann ihm das Einverständnis für den Schreibvorgang schnell zusenden. Genau so verhält es sich mit den Datenbankinstanzen, auf die der primäre Empfänger der Daten diese im weiteren Verlauf repliziert. Dem Client bleibt so einiges an Wartezeit erspart, was pro einzelnem Write keinen großen Unterschied macht, bei Tausenden Schreibzugriffen aber sehr wohl.
Die richtige Distribution wählen
Wer seine eigene Datenbank auf diese Art und Weise fit für das Skalieren in die Breite und für Hochverfügbarkeit machen will, steht allerdings vor einigen Hürden. Darunter die wichtigste: Welches Produkt darf es sein? Für den produktiven Einsatz von Galera bieten sich gerade nicht weniger als drei Varianten an, die für den produktiven Einsatz freigegeben sind und sie hängen von der Frage ab, welche Datenbank der Admin nutzt.
Die offensichtlichste Variante ist bis heute natürlich, das klassiche MySQL mit Galera zu kombinieren. Die Galera-Entwickler [2] stellen fertige Pakete für sämtliche gängigen Distributionen zur Verfügung. Diese lassen sich über die lokale Paketverwaltung schnell installieren. Komplementär bietet Galera auch eine fertig gepatchte MySQL-Version mit Galera an, die das Setup nochmal etwas leichter gestaltet. Dabei ist zu beachten, dass Galera aus zwei Teilen besteht: Einem Patch für MySQL und der eigentlichen Replikationsbibliothek, die den Patch in MySQL voraussetzt.
Viele Distributoren haben MySQL allerdings nach der Oracle-Übernahme aus dem eigenen Programm genommen und durch MariaDB ersetzt. Die gute Nachricht ist, dass Galera heute MariaDB standardmäßig beiliegt. Der Patch ist ab Werk in MariaDB integriert. Wer also eine halbwegs aktuelle MariaDB-Version sein eigen nennt, bekommt Galera als Dreingabe dazu. Es fällt nur die Installation des entsprechenden Paketes an, das den Linux-Distributionen der Gegenwart aber beiliegt. Ist das nicht der Fall, springt MariaDB selbst in die Bresche und liefert fertige Pakete.
Die dritte Variante sei der Vollständigkeit halber ebenfalls erwähnt: Perconas MySQL-Distribution "XtraDB Cluster" liegt Galera ebenfalls bei. Wer ohnehin bereits auf XtraDB setzt, ist mit diesem Ansatz also vermutlich am besten bedient.
Ob das Starten des Galera-Clusters erfolgreich war, findet der Admin über die "wsrep"-Statuseinträge heraus, die in jedem Galera-Cluster existieren.
Vorbereitungen treffen
Haben Sie sich für die Kombination aus MariaDB und Galera entschieden, sind auf den Zielsystemen zunächst ein paar Dinge zu beachten. Dieser Workshop geht im Folgenden davon aus, dass ein Galera-Cluster mit MariaDB auf Basis von drei Servern mit Ubuntu Linux 20.04 entstehen soll. Die Systeme sind frisch installiert und über redundante Netzwerkpfade – etwa per Bonding und EVPN-Multihoming – verbunden. Sind diese Anforderungen erfüllt, steht im nächsten Schritt die Installation von MariaDB und Galera an. Zwar liegt auch Ubuntu eine Galera-Version und MariaDB bei. Erfahrungsgemäß empfiehlt es sich allerdings, die Datenbankpakete zu nutzen, die MariaDB selbst zur Verfügung stellt, denn die sind in aller Regel deutlich frischer.
Um dieses Ziel zu erreichen, fügen Sie zunächst mittels
fügen im nächsten Schritt die Paketquelle für die MariaDB-Pakete dem System hinzu. Ein sudo apt update aktualisiert die Datenbank der verfügbaren Pakete. Schließlich holen Sie die MariaDB-Pakete samt Galera mittels
Von grundlegender Bedeutung für Galera ist, dass die Hosts einander mittels ihrer vollen Hostnamen erreichen können. Die Namensauflösung muss also funktionieren. Das stellen Sie relativ unkompliziert sicher, indem Sie die öffentlichen IP-Adressen der Systeme samt der vollständigen Hostnamen auf allen drei Systemen in "/etc/hosts" hinterlegen. Falls Sie einen lokalen DNS-Server für Ihre Domäne betreiben, dürfte dieser Schritt in den meisten Fällen ersatzlos entfallen.
Bevor Sie Galera an den Start bekommen, ist die Einrichtung von MariaDB auf den Systemen notwendig. Konkret geht es etwa darum, das lokale Passwort des Benutzers "root" für die Datenbank zu definieren. Obendrein sind ein paar Berechtigungen der zu MariaDB gehörenden Dateien im Dateisystem anzupassen. Praktischerweise liefert der Hersteller ein kleines Skript mit, das Ihnen diese Arbeit abnimmt. Führen Sie also sudo mysql_secure_installation auf allen Systemen aus und setzen Sie das Passwort für "root" in MariaDB. Die anderen Fragen beantworten Sie mit "y". Danach kann es mit der Einrichtung von Galera losgehen.
Zunächst öffnen Sie auf der Kommandozeile "/etc/mysql/mariadb.conf.d/50-server.cnf". Dort finden Sie eine Zeile mit "bind-address", die in der Standardkonfiguration dafür sorgt, dass MariaDB nur auf 127.0.0.1 lauscht. Das ist für Galera natürlich nutzlos, denn um Daten mit den anderen Knoten auszutauschen, muss Galera auf der öffentlichen Host-IP-Adresse lauschen, die natürlich einem privaten IP-Addressraum entspringen kann.
Legen Sie im nächsten Schritt die Datei "/etc/mysql/mariadb.conf.d/50-server.cnf" mit den Inhalten aus Listing 1 an. Dies tun Sie nur auf dem ersten Knoten des Clusters. Wichtig: Bei "wsrep_node_address" muss der Hostname des jeweiligen Systems stehen, und zwar ohne den FQDN. Heißt der Server also "server1.test", lautet der richtige Eintrag "server1".
Führen Sie auf Server 1 anschließend die beiden Befehle sudo galera_new_cluster und sudo systemctl restart mariadb aus. Hier ist etwas Hintergrundwissen hilfreich: Wenn Sie einen Galera-Cluster zum ersten Mal starten, weiß keine der drei Instanzen, welche denn nun eigentlich die "richtigen" Daten hat. Zwar sind im Beispiel die drei Datenbanken ohnehin leer, trotzdem muss der Administrator erstmalig definieren, wer den kanonischen Datensatz hat. Das geschieht im Beispiel über die Zeile "wsrep_cluster_address = gcomm://" in der zuvor angelegten Datei.
Auf den Knoten 2 und 3 legen Sie diese Datei ebenfalls an. Hier sind allerdings zwei Zeilen zu ändern. Die Zeile mit "wsrep_ cluster_address" muss dort "wsrep_cluster_address = gcomm://server1,server2,server3"" heißen. Und hinter "wsrep_node_address" muss der Hostnamen des jeweiligen Systems stehen, also "server2" oder "server3". Führen Sie danach das Kommando "systemctl restart mariadb" aus, um den Neustart von MariaDB zu erzwingen.
Loggen Sie sich anschließend bei einer der drei MariaDB-Instanzen mittels mysql -u root -p ein, geben Sie das Passwort an, das Sie zuvor für "root" festgelegt haben und rufen Sie in der MySQL-Shell den Befehl show status like 'wsrep_%'; auf. Sehen Sie beim Feld "wsrep_cluster_size" die Zahl "3", ist der Galera-Cluster erfolgreich konfiguriert. Falls Ihnen das als Test noch nicht genügt, können Sie mittels CREATE DATABASE test; eine Datenbank anlegen. Auf einem anderen Clusterknoten sollten Sie sich danach mittels desselben "mysql"-Befehls an MySQL anmelden können, und ein SHOW DATABASES; sollte die eben auf dem anderen System angelegte Datenbank zutage fördern.
Die Galera-Replikation kopiert übrigens auch Benutzer und Berechtigungen. Falls Sie auf einem System also einen Benutzer anlegen, existiert dieser automatisch auch in den anderen Datenbankinstanzen. Lediglich ein "FLUSH PRIVILEGES;" nach dem Hinzufügen ("GRANT") von Berechtigungen zu einzelnen Benutzern ist gegebenenfalls noch notwendig.
Auf Galera zugreifen
Ihr neuer Galera-Cluster hilft freilich nur bedingt, wenn Clients ihn nicht sinnvoll nutzen können. Die Herausforderung kommt dabei aus unerwarteter Ecke: Der klassische MySQL-Client, wie er für PHP, Go oder Python existiert, beherrscht die Angabe von Server-Pools nicht. Sie können einem Client also nicht sagen, nutze einen dieser drei Server. Stattdessen brauchen Sie wie erwähnt einen Loadbalancer.
Für welche Implementierung Sie sich hier entscheiden, hängt auch von den Begebenheiten vor Ort ab. Falls Sie eine Loadbalancer-Appliance nutzen, zum Beispiel von F5, bietet diese mit einiger Wahrscheinlichkeit SQL-Loadbalancing an. Hier hinterlegen Sie dann als Ziel einfach Ihre drei Galera-Instanzen mit derselben Priorität. Falls das jeweilige System eine Möglichkeit zum Monitoring bietet, geht auch das mit Galera und MariaDB. Hier könnten Sie etwa das zuvor beschriebene MySQL-Query nutzen und auf allen Datenbankinstanzen den Wert von "wsrep_connected" auslesen. Ist dieser auf "OFF", ist er nicht Teil des Clusters und sollte für Verbindungen nicht als Ziel dienen.
Wer stattdessen einen Loadbalancer für MySQL selber bauen möchte, findet dazu im Open-Source-Werkzeugkasten die passenden Mittel. Ein ganz einfacher HAProxy etwa eignet sich für Galera hervorragend. Die Codership-Entwickler stellen in ihrer Dokumentation sogar eine Anleitung bereit, um HAProxy als Loadbalancer für Galera zu verwenden [3]. Der Vollständigkeit halber sei allerdings darauf hingewiesen, dass der Loadbalancer selbst dann auch irgendwie hochverfügbar sein muss. Das ist mit Pacemaker zu erreichen; alternative Möglichkeiten stehen in Form von VRRP aber ebenfalls zur Verfügung.
Fazit
Galera bietet eine einfach zu konfigurierende, erprobte und verlässliche Methode für Multi-Master-Replikation mit MySQL oder Galera. Dass der komplexeste Teil des Setups de facto die Wahl der Kombination aus MariaDB oder MySQL mit Galera ist, spricht für die Reife der Technik. In dasselbe Horn stößt die Tatsache, dass Galera bereits ein paar Jahre als erprobte Lösung auf dem Buckel hat. In vielen
Boxed-Lösungen wie Red Hats Open-Stack-Distribution ist es integrierter Bestandteil und leistet dort zuverlässig Dienst.
Admins sehen sich heute mit der Notwendigkeit konfrontiert, Datenbanken in die Breite zu skalieren. Wer feststellt, dass ein einzelner Datenbankserver die Last eines Setups nicht mehr abferdern kann, sollte sich mit Galera befassen. Doch oft genug sind Setups mit MariaDB oder MySQL auch deshalb langsam, weil das Datenbankdesign schlecht ist. Hier nutzt ein MySQL-Consultant vermutlich mehr als ein Galera-Cluster, zumal der die langsame Datenbank in drei langsame Datenbanken verwandeln würde. Galera sollte deshalb nicht als Wunderwerkzeug gegen schlechtes Datenbankdesign verstanden werden, sondern als zuverlässige Replikationslösung für das Skalieren in die Breite.