Fünf Load Balancer und Reverse Proxys für MySQL
Lastenverteiler
Mit der klassischen Master-Slave-Replikation, der Galera Engine und Oracles Group Replication gibt es im MySQL-Umfeld inzwischen drei verschiedene Möglichkeiten, hochverfügbare, flexibel skalierende Datenbanksysteme zu bauen. Diese Mechanismen kümmern sich jedoch nicht darum, wie die Querys zu den einzelnen Cluster-Nodes kommen. Verschiedene Werkzeuge füllen die Lücke.
Der klassische Weg, Daten zwischen mehreren MySQL-Servern auf dem gleichen Stand zu halten, ist die asynchrone Master-Slave-Replikation. Hierbei verarbeitet ein Master-Server alle datenverändernden Querys, während eine im Prinzip beliebige Zahl von Slave-Servern sich die Änderungen bei diesem abholt und damit die lesenden Anfragen bedient. In den letzten Jahren haben sich die zwei recht ähnlichen Cluster-Lösungen Galera und MySQL Group Replication dazugesellt. Sie beherrschen sogar einen fast synchronen Betrieb und erlauben – mit Einschränkungen – das Schreiben auf mehrere Datenbank-Nodes. Diesen Ansätzen gemein ist, dass ein Datenbestand auf mehreren Serverinstanzen verteilt vorliegt und es einen Mechanismus gibt, der sicherstellt, dass eine Datenänderung zeitnah auf allen Instanzen ankommt.
Wenn sich eine Datenbank auf mehrere Rechner verteilt, stellt sich jedoch unweigerlich die Frage, wie man die hinzugewonnene Ausfallsicherheit und (Lese-)Kapazität am besten nutzen kann. Schließlich kann die Datenbank jetzt auf mehreren Instanzen Anfragen beantworten, während die anfragende Anwendung fast immer nur eine Instanz (IP-Adresse/Port) ansprechen kann. Ausnahmen sind Anwendungen, die auf Konnektoren aufsetzen, die einen Failover-Modus unterstützen, wie den JDBC-Treiber Connector/J von Oracle oder den noch nicht sehr weit verbreiteten PHP-Treiber mysqlnd_ms.
Wenn also Datenbankanfragen ohne Wissen und Unterstützung der Anwendung auf mehrere Nodes verteilt werden sollen, ist ein Load Balancer oder Proxy vonnöten. Ob dieser zur Erhöhung der Verfügbarkeit oder zur Steigerung des Durchsatzes zum Einsatz kommt, ist dabei irrelevant.
Redundanzbedarf reduziert
Auch wenn im Folgenden immer wieder von Proxys die Rede ist, handelt es sich im Grunde um Reverse Proxys. Die Clients verbinden sich nicht mit dem finalen Datenbank-Node (den sie ja nicht kennen), sondern mit dem Reverse-Proxy-Server. Dieser reicht die Anfrage dann nach Parametern wie Verfügbarkeit, Auslastung und Antwortzeiten an einen Datenbank-Node weiter.
Klassisch verwendet man Load Balancer für die zentrale Verteilung eingehender Requests auf eine Reihe von Worker-Nodes. Hierbei ist der Lastenverteiler oder Proxy immer eine eigenständige Komponente im Netzwerk, die – meist auf dedizierter Hardware und mit komplexen HA-Funktionen ausgestattet – ihren Dienst tut.
In modernen, von Virtualisierung und Containern geprägten Umgebungen ist ein solches Setup immer weniger sinnvoll. Stattdessen ist der Platz des Proxys heute direkt neben der Anwendung, sodass beispielsweise pro Webserver, der eine PHP-Anwendung bereitstellt, eine eigene Proxy-Instanz zum Einsatz kommt. Diese Herangehensweise hat den Vorteil, dass Proxy-Knoten nicht mehr redundant ausgelegt sein müssen. Der in der Vergangenheit für den reibungslosen Übergang zwischen zwei Nodes notwendige Aufwand, bei dem oft über das Virtual Router Redundancy Protocol (VRRP) oder das Ressourcenverwaltungstool Pacemaker eine virtuelle IP-Adresse von einem Node auf einen anderen umgezogen werden musste, entfällt. Das steigert die Flexibilität. Außerdem steigt die Erfolgsrate bei tatsächlichen Problemen. Oft sind nämlich gerade die selten bis nie erprobten Failover-Szenarien die Ursache für längere Ausfälle der Infrastruktur.
Wo laufen sie denn?
Die im Folgenden vorgestellten Load Balancer und Proxys befinden sich entweder auf Layer 4 oder Layer 7 des OSI-Schichtenmodells. Am weitesten verbreitet sind Lösungen, die auf Layer 4, der Transportschicht, aufsetzen. Die TCP-Verbindung wird zwischen Client und Server aufgebaut, der Proxy leitet die Pakete – ohne von deren Inhalt Kenntnis zu haben – lediglich zum Server weiter.
Ein Layer-7-Proxy hingegen arbeitet auf der Applikationsschicht des OSI-Modells und „versteht“ damit das MySQL-Protokoll. Das bedeutet, dass er – je nach Inhalt einer Query – unterschiedliche Aktionen ausführen kann. Wenn erforderlich, kann er eine Query auf dem Weg zum Server auch verändern.
Bei einem Layer-7-Proxy hat man es stets mit zwei TCP-Verbindungen zu tun. Der Client baut eine Verbindung zum Proxy auf und der Proxy wiederum eine zum Datenbank-Node. Das hat auch Einfluss auf die Geschwindigkeit. Layer-7-Proxys bieten meist die Option des Connection Pooling, bei dem die Verbindung vom Proxy zum Datenbankknoten dauerhaft bestehen bleibt und nicht bei jeder eingehenden Verbindung neu aufgebaut werden muss.