MariaDB Maxscale: Die fehlende Komponente für verteilte MySQL-Setups

MariaDB Maxscale: Die fehlende Komponente für verteilte MySQL-Setups

MariaDB hat mit Maxscale 1.0 GA einen flexiblen MySQL-Proxy veröffentlicht, der die Skalierung von MySQL-Installationen erheblich vereinfachen soll. Er soll zugleich als MySQL-Loadbalancer und Binlog-Server eingesetzt werden können. Die Software ermöglicht es, Datenbank-Querys anhand von Regeln auf unterschiedliche MySQL-Server und -Cluster zu verteilen, ohne dass die eigentliche Applikation angepasst werden muss.
MySQL lässt sich horizontal, also durch das Hinzufügen weiterer Server skalieren. Das geht durch Replikation der Daten von einem auf einen oder mehrere Server, das Sharding genannte Aufteilen der Daten, wenn ein Server die Schreiblast nicht bewältigen kann, oder den Aufbau eines Clusters. Durch verteilte Setups werden die Datenbanken zudem sicherer vor Ausfällen. All diese Ansätze aber erhöhen die Komplexität, was im Betrieb zu höheren Kosten führt. Zudem muss in aller Regel die eingesetzte Software geeignet sein, ein verteiltes Datenbank-Setup effizient zu nutzen.
Datenbank-Proxys sollen helfen, die Komplexität zu reduzieren, denn der Proxy verteilt die Datenbank-Anfragen auf die verschiedenen Datenbank-Server. Es ist also nicht mehr nötig, die Applikation anzupassen. Allerdings sind Lösungen wie MySQL Proxy oder HAProxy nicht überzeugend.
Maxscale versteht Querys dank MariaDB-Parser
Mit Maxscale bietet MariaDB nun eine weitere Option an, die seit kurzem in der ersten stabilen Version 1.0 GA zur Verfügung steht. Der Unterschied zu den zuvor genannten Datenbank-Proxys ist auf den ersten Blick groß: Maxscale weiß, dass es mit Datenbanken spricht und kennt, richtig konfiguriert, den Zustand der Backend-Server. So kann Maxscale reagieren, wenn ein Slave-Server nicht mit seinem Master synchron ist oder die Replikation nicht mehr funktioniert.
Darüber hinaus versteht Maxscale die Querys, denn es verwendet den gleichen Parser wie MariaDB. So kann die Software anhand von Filtern und Regeln unterschiedlich reagieren, um die Anfragen beispielsweise auf einen oder mehrere Datenbank-Server zu verteilen und die Querys, wenn nötig, verändern. Auch erhält der Nutzer ein zentrales Performance-Log über alle Server und kann veraltete Applikationen an neue Datenbank-Versionen anbinden.
Mit Plugins flexibel erweiterbar
Maxscale lässt sich dabei mittels Plugins erweitern. So kann beispielsweise Sharding implementiert werden, ohne dass die Applikation davon etwas mitbekommt. Auch eine MySQL-Firewall kann umgesetzt werden, die SQL-Injection-Angriffe verhindert. Auch ist es so möglich, den Master-Server in einem Setup umzustellen, ohne dass die Applikation angepasst werden muss, oder einzelne Querys mit Hilfe eines regulären Ausdrucks auf einen bestimmten Server zu leiten.
Per Plugin kann Maxscale auch als Binlog-Server eingesetzt werden. Er fungiert dabei gegenüber dem MySQL-Master als Client, speichert die Binlogs zwischen und tritt gegenüber den Slave-Servern als Master auf. Da Maxscale darüber hinaus aber keine Daten speichert und keine Querys ausführt, ist ein Binlog-Server mit Maxscale schneller und kleiner als einer mit MySQL oder MariaDB.
Installation und Konfiguration
Die Installation von Maxscale selbst ist schnell erledigt. Da wir bei SysEleven Gentoo als primäre Distribution einsetzen, haben wir Ebuild für Maxscale geschrieben, das bei Github zum Download bereitsteht. Für einen ersten Test haben wir einen MariaDB Galera Cluster verwendet.
Die Konfiguration des Maxscale-Proxys besteht ganz grob aus zwei Teilen: den sogenannten Services und den dazugehörigen Listenern. Im Listener wird definiert, wie Maxscale Anfragen annimmt und an welchen Dienst (Service) diese weitergereicht werden. Im Service wird dann festgelegt, auf welche Backend-Server die Anfragen in welcher Art und Weise weitergereicht werden sollen.
Beispiel:

[GaleraSplitRouter]
type=service
router=readconnroute
router_options=synced
servers=srv1,srv2,srv3
user=maxscale
passwd=maxpass

Der dazugehörige Listener sieht so aus:

[GaleraSplitListener]
type=listener
service=GaleraSplitRouter
protocol=MySQLClient
address=192.0.0.1
port=3306

Nach dem Start von Maxscale lauscht Maxscale nun also auf 192.0.0.1:3306 und reicht Querys an die Server srv1, srv2 und srv3 weiter. Auf der Kommandozeile (CLI) sieht das folgendermaßen aus:

MaxScale> show servers
Server 0xa41e40 (srv1)
 Server: 192.168.122.200
 Status: Slave, Synced, Running
 Protocol: MySQLBackend
 Port: 3306
 Server Version: 10.0.14-MariaDB-wsrep
 Node Id: 2
 Master Id: -1
 Repl Depth: 0
 Number of connections: 0
 Current no. of conns: 0
 Current no. of operations: 0
Server 0xa41d30 (srv2)
 Server: 192.168.122.201
 Status: Master, Synced, Running
 Protocol: MySQLBackend
 Port: 3306
 Server Version: 10.0.14-MariaDB-wsrep
 Node Id: 0
 Master Id: -1
 Repl Depth: 0
 Number of connections: 1
 Current no. of conns: 1
 Current no. of operations: 0
Server 0xa41c20 (srv3)
 Server: 192.168.122.202
 Status: Slave, Synced, Running
 Protocol: MySQLBackend
 Port: 3306
 Server Version: 10.0.14-MariaDB-wsrep
 Node Id: 1
 Master Id: -1
 Repl Depth: 0
 Number of connections: 1
 Current no. of conns: 1
 Current no. of operations: 0
MaxScale>

Die Basisfunktionalität ist also hergestellt. Im Maxscale-CLI können wir nun Performance-Werte abrufen oder auch Backend-Server in den Maintenance-Modus versetzen:

MaxScale> show eventstats
Event statistics.
Maximum queue time: 000ms
Maximum execution time: 100ms
Maximum event queue length: 2
Current event queue length: 1
| Number of events
    Duration | Queued | Executed
-------------+--------+-----------
     < 100ms | 4464   | 4460
 100 - 200ms | 0      | 3
 200 - 300ms | 0      | 0
 300 - 400ms | 0      | 0
MaxScale&gt; set server srv1 maintenance
MaxScale&gt; show server srv1
Server 0xa41e40 (srv1)
 Server: 192.168.122.200
 Status: Maintenance, Slave, Synced, Running
 Protocol: MySQLBackend
 Port: 3306
 Server Version: 10.0.14-MariaDB-wsrep
 Node Id: 2
 Master Id: -1
 Repl Depth: 0
 Number of connections: 0
 Current no. of conns: 0
 Current no. of operations: 0
MaxScale>

Filter
Wie eingangs schon erwähnt, lassen sich Querys anhand von Filtern auf verschiedene Backend-Server verteilen, je nach Art der Query. So ist es beispielsweise möglich, MariaDB Galera Cluster und Standard-MySQL-Server miteinander zu mischen. Besonders interessant ist der sogenannte Readwrite-Splitrouter, da er auf den Einsatz mit einem Master-Slave-Setup abzielt. Er lässt sich wie folgt mit einem typischen Master-Slave-Setup einrichten:

[RW Split Router]
 type=service
 router=readwritesplit
 servers=server1,server2
 user=maxuser
 passwd=maxpass
 max_slave_connections=100%
 max_slave_replication_lag=21
[RW Split Listener]
type=listener
service=RW Split Router
protocol=MySQLClient
port=3306
address=192.0.0.1

In der Applikation gibt man nun nur 192.0.0.1 als Datenbank-Host an, den Rest erledigt Maxscale. Konkret bedeutet das: Querys, die nur lesend auf Daten zugreifen, werden auf den Slave-Server geleitet. Querys, die Daten schreiben oder verändern, landen auf dem Master-Server. Werden Daten sehr viel häufiger gelesen als geschrieben, wie es bei Web-Anwendungen üblicherweise der Fall ist, lässt sich das Setup leicht um weitere Slave-Server ergänzen.

 MaxScale> show service "RW Split Router"
 Service 0x1f51210
 Service: RW Split Router
 Router: readwritesplit (0x7f0855427420)
 State: Started
 Number of router sessions: 11
 Current no. of router sessions: 0
 Number of queries forwarded: 335
 Number of queries forwarded to master: 123
 Number of queries forwarded to slave: 212
 Number of queries forwarded to all: 80
 Started: Mon Jan 19 14:38:53 2015
 Root user access: Disabled
 Backend databases
 192.168.122.151:3306 Protocol: MySQLBackend
 192.168.122.150:3306 Protocol: MySQLBackend
 Users data: 0x7f0840006350
 Total connections: 12
 Currently connected: 1
 MaxScale>

Welche Querys Maxscale als schreibend oder lesend kategorisiert, ist im Read-Write-Splitting-Tutorial von MariaDB dokumentiert. Kurz zusammengefasst werden folgende Querys an den Master geschickt:
Write-Querys die an den Server gesendet werden:

  • alle Querys, die eine Transaktion eröffnen
  • Aufrufe von Stored-Procedures und nutzerdefinierten Funktionen
  • DDL-Querys (DROP, CREATE, ALTER TABLE etc.)
  • die Ausführung (EXECUTE) von Prepared-Statements
  • alle Querys, die temporäre Tabellen nutzen

Folgende Querys werden an den Slave geschickt:

  • Read-Only-Querys
  • Read-Only-Querys auf System- oder nutzerdefinierte Variablen
  • SHOW-Querys
  • Aufrufe von System-Funktionen

Daneben gibt es nur Querys, die an alle Session-Backends geleitet werden:

  • SET-Querys
  • USE <dbname>
  • Zuweisungen von Variablen (@myvar := 5) in Read-Only-Querys
  • PREPARE-Querys
  • Kommandos wie QUIT, PING, STMT RESET, CHANGE USER etc.

Auf den ersten Blick macht Maxscale einen hervorragenden Eindruck. Der Nutzer kann Anfragen auf Master und Slaves verteilen, ohne Änderungen an der Applikation vornehmen zu müssen. Das eröffnet uns als Provider sehr viele Möglichkeiten, unsere Kunden in Hinblick auf Performance und Ausfallsicherheit noch besser zu unterstützen.
Derzeit arbeiten wir daran einen ReadWrite Splitrouter für Oxid anzupassen. Damit wäre dann eine Lastverteilung ohne Anpassen von Oxid selbst möglich. Aber auch ohne RW-Splitrouter lässt sich nun ein unterbrechungsfreier Betrieb von Oxid gewährleisten, da wir, ein Mysql Master/Master Setup vorausgesetzt, mühelos zwischen den Mastern umschalten können.

Share this post

Comment (1)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.