MariaDB MaxScale ist ein erweiterter Plug-in-Datenbank-Proxy für MariaDB-Datenbankserver. Es befindet sich zwischen Clientanwendungen und den Datenbankservern und leitet Clientabfragen und Serverantworten weiter. MaxScale überwacht auch die Server, sodass Änderungen im Serverstatus oder in der Replikationstopologie schnell bemerkt werden. Dies macht MaxScale zu einer natürlichen Wahl für die Steuerung von Failover und ähnlichen Funktionen.
In dieser zweiteiligen Blogserie geben wir eine vollständige Anleitung zum Ausführen von MariaDB MaxScale auf Docker. Dieser Teil behandelt die Bereitstellung als eigenständiger Docker-Container und MaxScale-Clustering über Docker Swarm für Hochverfügbarkeit.
MariaDB MaxScale auf Docker
In Docker Hub sind eine Reihe von MariaDB-Docker-Images verfügbar. In diesem Blog verwenden wir das von MariaDB gepflegte und veröffentlichte offizielle Image mit dem Namen „mariadb/maxscale“ (Tag:Latest). Das Bild ist etwa 71 MB groß. Zum jetzigen Zeitpunkt ist das Image mit MaxScale 2.3.4 als Teil der erforderlichen Pakete vorinstalliert.
Im Allgemeinen sind die folgenden Schritte erforderlich, um eine MaxScale mit diesem Image in einer Containerumgebung auszuführen:
- Eine laufende MariaDB-Replikation (Master-Slave oder Master-Master)/Galera-Cluster oder NDB-Cluster
- Erstellen und gewähren Sie einen Datenbankbenutzer, der für die MaxScale-Überwachung dediziert ist
- Bereiten Sie die MaxScale-Konfigurationsdatei vor
- Mappen Sie die Konfigurationsdatei in einen Container oder laden Sie sie in Kubernetes ConfigMap oder Docker Swarm Configs
- Starten Sie den Container/Pod/Dienst/Replikatsatz
Beachten Sie, dass MaxScale ein Produkt von MariaDB ist, was bedeutet, dass es auf MariaDB-Server zugeschnitten ist. Die meisten Funktionen sind weiterhin mit MySQL kompatibel, mit Ausnahme einiger Teile wie zum Beispiel GTID-Handhabung, Galera-Cluster-Konfiguration und interne Datendateien. Die Version, die wir verwenden werden, ist 2.3.4, die unter der Business Source License (BSL) veröffentlicht wird. Es ermöglicht, dass der gesamte Code offen ist und die Nutzung unter DREI Servern kostenlos ist. Wenn die Nutzung über drei Backend-Server hinausgeht, muss das Unternehmen, das es verwendet, für ein kommerzielles Abonnement bezahlen. Nach einem bestimmten Zeitraum (2 Jahre im Fall von MaxScale) wechselt die Veröffentlichung zur GPL und die gesamte Nutzung ist kostenlos.
Nur um das klarzustellen, da dies eine Testumgebung ist, können wir mehr als 2 Knoten haben. Wie auf der MariaDB-BSL-FAQ-Seite angegeben:
F:Kann ich unter BSL lizenzierte MariaDB-Produkte in Test- und Entwicklungsumgebungen verwenden?
A:Ja, in Test- und Entwicklungsumgebungen außerhalb der Produktion können Sie unter BSL lizenzierte Produkte verwenden, ohne ein Abonnement von MariaDB zu benötigen
In dieser exemplarischen Vorgehensweise haben wir bereits eine MariaDB-Replikation mit drei Knoten, die mithilfe von ClusterControl bereitgestellt wird. Das folgende Diagramm veranschaulicht das Setup, das wir bereitstellen werden:
Unsere Systemarchitektur besteht aus:
- mariadb1 - 192.168.0.91 (Master)
- mariadb2 - 192.168.0.92 (Sklave)
- mariadb3 - 192.168.0.93 (Sklave)
- docker1 - 192.168.0.200 (Docker-Host für Container - maxscale, App)
Vorbereitung des MaxScale-Benutzers
Erstellen Sie zunächst einen MySQL-Datenbankbenutzer für MaxScale und erlauben Sie alle Hosts im Netzwerk 192.168.0.0/24:
MariaDB> CREATE USER 'maxscale'@'192.168.0.%' IDENTIFIED BY 'my_s3cret';
Gewähren Sie dann die erforderlichen Berechtigungen. Wenn Sie nur die Backend-Server mit Load-Balancing überwachen möchten, würden die folgenden Berechtigungen ausreichen:
MariaDB> GRANT SHOW DATABASES ON *.* TO 'maxscale'@'192.168.0.%';
MariaDB> GRANT SELECT ON `mysql`.* TO 'maxscale'@'192.168.0.%';
MaxScale kann jedoch viel mehr als das Weiterleiten von Abfragen. Es hat die Fähigkeit, Failover und Switchover durchzuführen, zum Beispiel einen Slave zu einem neuen Master hochzustufen. Dies erfordert SUPER- und REPLICATION CLIENT-Berechtigungen. Wenn Sie diese Funktion nutzen möchten, weisen Sie dem Benutzer stattdessen ALLE PRIVILEGIEN zu:
mysql> GRANT ALL PRIVILEGES ON *.* TO [email protected]'192.168.0.%';
Das war's für den Benutzerteil.
MaxScale-Konfigurationsdatei vorbereiten
Das Image erfordert, dass dem Container eine funktionierende Konfigurationsdatei zugeordnet wird, bevor es gestartet wird. Die im Container bereitgestellte minimale Konfigurationsdatei wird uns nicht dabei helfen, den gewünschten Reverse-Proxy zu erstellen. Daher muss die Konfigurationsdatei vorher vorbereitet werden.
Die folgende Liste kann uns dabei helfen, die erforderlichen grundlegenden Informationen zum Erstellen unserer Konfigurationsdatei zu sammeln:
- Cluster-Typ – MaxScale unterstützt MariaDB-Replikation (Master-Slave, Master-Master), Galera-Cluster, Amazon Aurora, MariaDB ColumnStore und NDB-Cluster (auch bekannt als MySQL-Cluster).
- Back-End-IP-Adresse und/oder Hostname – Erreichbare IP-Adresse oder Hostname für alle Back-End-Server.
- Routing-Algorithmus – MaxScale unterstützt zwei Arten von Abfrage-Routing – Read-Write-Splitting und Load-Balancing in Round-Robin.
- Port zum Abhören durch MaxScale – Standardmäßig verwendet MaxScale Port 4006 für Round-Robin-Verbindungen und 4008 für geteilte Read-Write-Verbindungen. Sie können den UNIX-Socket verwenden, wenn Sie möchten.
Erstellen Sie im aktuellen Verzeichnis eine Textdatei namens maxscale.cnf, damit wir sie beim Start dem Container zuordnen können. Fügen Sie die folgenden Zeilen in die Datei ein:
########################
## Server list
########################
[mariadb1]
type = server
address = 192.168.0.91
port = 3306
protocol = MariaDBBackend
serv_weight = 1
[mariadb2]
type = server
address = 192.168.0.92
port = 3306
protocol = MariaDBBackend
serv_weight = 1
[mariadb3]
type = server
address = 192.168.0.93
port = 3306
protocol = MariaDBBackend
serv_weight = 1
#########################
## MaxScale configuration
#########################
[maxscale]
threads = auto
log_augmentation = 1
ms_timestamp = 1
syslog = 1
#########################
# Monitor for the servers
#########################
[monitor]
type = monitor
module = mariadbmon
servers = mariadb1,mariadb2,mariadb3
user = maxscale
password = my_s3cret
auto_failover = true
auto_rejoin = true
enforce_read_only_slaves = 1
#########################
## Service definitions for read/write splitting and read-only services.
#########################
[rw-service]
type = service
router = readwritesplit
servers = mariadb1,mariadb2,mariadb3
user = maxscale
password = my_s3cret
max_slave_connections = 100%
max_sescmd_history = 1500
causal_reads = true
causal_reads_timeout = 10
transaction_replay = true
transaction_replay_max_size = 1Mi
delayed_retry = true
master_reconnection = true
master_failure_mode = fail_on_write
max_slave_replication_lag = 3
[rr-service]
type = service
router = readconnroute
servers = mariadb1,mariadb2,mariadb3
router_options = slave
user = maxscale
password = my_s3cret
##########################
## Listener definitions for the service
## Listeners represent the ports the service will listen on.
##########################
[rw-listener]
type = listener
service = rw-service
protocol = MariaDBClient
port = 4008
[ro-listener]
type = listener
service = rr-service
protocol = MariaDBClient
port = 4006
Ein paar Erklärungen für jeden Abschnitt:
- Serverliste - Die Backend-Server. Definieren Sie jeden MariaDB-Server dieses Clusters in einer eigenen Zeilengruppe. Der Zeilenname wird verwendet, wenn wir die Dienstdefinition weiter unten spezifizieren. Der Komponententyp muss "Server" sein.
- MaxScale-Konfiguration - Definieren Sie dort alle MaxScale-bezogenen Konfigurationen.
- Monitor-Modul - Wie MaxScale die Backend-Server überwachen soll. Der Komponententyp muss "Monitor" sein, gefolgt von einem der Überwachungsmodule. Eine Liste der unterstützten Monitore finden Sie unter MaxScale 2.3 Monitors.
- Dienst - Wohin die Abfrage geleitet werden soll. Der Komponententyp muss "Service" sein. Eine Liste der unterstützten Router finden Sie unter MaxScale 2.3 Routers.
- Listener - Wie MaxScale auf eingehende Verbindungen hören soll. Es kann eine Port- oder Socket-Datei sein. Der Komponententyp muss „Listener“ sein. Üblicherweise sind Zuhörer an Dienste gebunden.
Im Grunde möchten wir also, dass MaxScale auf zwei Ports lauscht, 4006 und 4008. Port 4006 ist speziell für Round-Robin-Verbindungen, geeignet für Nur-Lese-Workloads für unsere MariaDB-Replikation, während Port 4008 speziell für kritische Lese- und Schreib-Workloads ist. Wir möchten auch MaxScale verwenden, um im Falle eines Failovers, Switchovers oder Wiederbeitretens von Slaves Aktionen an unserer Replikation durchzuführen, daher verwenden wir das Monitormodul namens "mariadbmon".
Container ausführen
Wir sind jetzt bereit, unseren eigenständigen MaxScale-Container auszuführen. Ordnen Sie die Konfigurationsdatei mit -v zu und stellen Sie sicher, dass beide Listener-Ports 4006 und 4008 veröffentlicht werden. Optional können Sie die MaxScale-REST-API-Schnittstelle an Port 8989 aktivieren:
$ docker run -d \
--name maxscale \
--restart always \
-p 4006:4006 \
-p 4008:4008 \
-p 8989:8989 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale
Bestätigen Sie mit:
$ docker logs -f maxscale
...
2019-06-14 07:15:41.060 notice : (main): Started REST API on [127.0.0.1]:8989
2019-06-14 07:15:41.060 notice : (main): MaxScale started with 8 worker threads, each with a stack size of 8388608 bytes.
Stellen Sie sicher, dass beim Betrachten der obigen Protokolle keine Fehler angezeigt werden. Überprüfen Sie, ob die Docker-Proxy-Prozesse die veröffentlichten Ports abhören – 4006, 4008 und 8989:
$ netstat -tulpn | grep docker-proxy
tcp6 0 0 :::8989 :::* LISTEN 4064/docker-proxy
tcp6 0 0 :::4006 :::* LISTEN 4092/docker-proxy
tcp6 0 0 :::4008 :::* LISTEN 4078/docker-proxy
Zu diesem Zeitpunkt läuft unser MaxScale und kann Abfragen verarbeiten.
MaxCtrl
MaxCtrl ist ein Befehlszeilen-Verwaltungsclient für MaxScale, der die MaxScale-REST-API für die Kommunikation verwendet. Es ist als Ersatzsoftware für den alten MaxAdmin-Befehlszeilenclient gedacht.
Um die MaxCtrl-Konsole aufzurufen, führen Sie den Befehl „maxctrl“ im Container aus:
$ docker exec -it maxscale maxctrl
maxctrl: list servers
┌──────────┬──────────────┬──────┬─────────────┬─────────────────┬─────────────┐
│ Server │ Address │ Port │ Connections │ State │ GTID │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb1 │ 192.168.0.91 │ 3306 │ 0 │ Master, Running │ 0-5001-1012 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb2 │ 192.168.0.92 │ 3306 │ 0 │ Slave, Running │ 0-5001-1012 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb3 │ 192.168.0.93 │ 3306 │ 0 │ Slave, Running │ 0-5001-1012 │
└──────────┴──────────────┴──────┴─────────────┴─────────────────┴─────────────┘
Um zu überprüfen, ob alles in Ordnung ist, führen Sie einfach die folgenden Befehle aus:
maxctrl: list servers
maxctrl: list services
maxctrl: list filters
maxctrl: list sessions
Um weitere Informationen zu jeder Komponente zu erhalten, stellen Sie stattdessen den Befehl „show“ voran, zum Beispiel:
maxctrl: show servers
┌──────────────────┬──────────────────────────────────────────┐
│ Server │ mariadb3 │
├──────────────────┼──────────────────────────────────────────┤
│ Address │ 192.168.0.93 │
├──────────────────┼──────────────────────────────────────────┤
│ Port │ 3306 │
├──────────────────┼──────────────────────────────────────────┤
│ State │ Slave, Running │
├──────────────────┼──────────────────────────────────────────┤
│ Last Event │ new_slave │
├──────────────────┼──────────────────────────────────────────┤
│ Triggered At │ Mon, 17 Jun 2019 08:57:59 GMT │
├──────────────────┼──────────────────────────────────────────┤
│ Services │ rw-service │
│ │ rr-service │
├──────────────────┼──────────────────────────────────────────┤
│ Monitors │ monitor │
├──────────────────┼──────────────────────────────────────────┤
│ Master ID │ 5001 │
├──────────────────┼──────────────────────────────────────────┤
│ Node ID │ 5003 │
├──────────────────┼──────────────────────────────────────────┤
│ Slave Server IDs │ │
├──────────────────┼──────────────────────────────────────────┤
│ Statistics │ { │
│ │ "connections": 0, │
│ │ "total_connections": 0, │
│ │ "persistent_connections": 0, │
│ │ "active_operations": 0, │
│ │ "routed_packets": 0, │
│ │ "adaptive_avg_select_time": "0ns" │
│ │ } │
├──────────────────┼──────────────────────────────────────────┤
│ Parameters │ { │
│ │ "address": "192.168.0.93", │
│ │ "protocol": "MariaDBBackend", │
│ │ "port": 3306, │
│ │ "extra_port": 0, │
│ │ "authenticator": null, │
│ │ "monitoruser": null, │
│ │ "monitorpw": null, │
│ │ "persistpoolmax": 0, │
│ │ "persistmaxtime": 0, │
│ │ "proxy_protocol": false, │
│ │ "ssl": "false", │
│ │ "ssl_cert": null, │
│ │ "ssl_key": null, │
│ │ "ssl_ca_cert": null, │
│ │ "ssl_version": "MAX", │
│ │ "ssl_cert_verify_depth": 9, │
│ │ "ssl_verify_peer_certificate": true, │
│ │ "disk_space_threshold": null, │
│ │ "type": "server", │
│ │ "serv_weight": "1" │
│ │ } │
└──────────────────┴──────────────────────────────────────────┘
Verbindung zur Datenbank herstellen
Dem Datenbankbenutzer der Anwendung muss der MaxScale-Host gewährt werden, da er aus Sicht des MariaDB-Servers nur den MaxScale-Host sehen kann. Betrachten Sie das folgende Beispiel ohne MaxScale im Bild:
- Datenbankname:myapp
- Benutzer:myapp_user
- Host:192.168.0.133 (Anwendungsserver)
Um dem Benutzer den Zugriff auf die Datenbank innerhalb des MariaDB-Servers zu ermöglichen, muss die folgende Anweisung ausgeführt werden:
MariaDB> CREATE USER 'myapp_user'@'192.168.0.133' IDENTIFIED BY 'mypassword';
MariaDB> GRANT ALL PRIVILEGES ON myapp.* to 'myapp_user'@'192.168.0.133';
Mit MaxScale im Bild muss stattdessen die folgende Anweisung ausgeführt werden (ersetzen Sie die IP-Adresse des Anwendungsservers durch die IP-Adresse von MaxScale, 192.168.0.200):
MariaDB> CREATE USER 'myapp_user'@'192.168.0.200' IDENTIFIED BY 'mypassword';
MariaDB> GRANT ALL PRIVILEGES ON myapp.* to 'myapp_user'@'192.168.0.200';
Von der Anwendung aus gibt es zwei Ports, die Sie verwenden können, um sich mit der Datenbank zu verbinden:
- 4006 – Round-Robin-Listener, geeignet für schreibgeschützte Workloads.
- 4008 – Split-Listener für Lese- und Schreibvorgänge, geeignet für Schreib-Workloads.
Wenn Ihre Anwendung nur einen MySQL-Port angeben darf (z. B. Wordpress, Joomla usw.), wählen Sie stattdessen den RW-Port 4008. Dies ist unabhängig vom Clustertyp die sicherste Endpunktverbindung. Wenn Ihre Anwendung jedoch Verbindungen zu mehreren MySQL-Ports verarbeiten kann, können Sie die Lesevorgänge an den Round-Robin-Listener senden. Dieser Listener hat weniger Overhead und ist im Vergleich zum geteilten Read-Write-Listener viel schneller.
Stellen Sie für unser MariaDB-Replikations-Setup eine Verbindung zu einem dieser Endpunkte als Datenbank-Host/Port-Kombination her:
- 192.168.0.200 Port 4008 – MaxScale – lesen/schreiben oder nur schreiben
- 192.168.0.200 Port 4006 – MaxScale – balanciert schreibgeschützt
- 192.168.0.91 Port 3306 – MariaDB-Server (Master) – Lesen/Schreiben
- 192.168.0.92 Port 3306 – MariaDB-Server (Slave) – schreibgeschützt
- 192.168.0.93 Port 3306 – MariaDB-Server (Slave) – schreibgeschützt
Hinweis:Für Multi-Master-Clustertypen wie Galera Cluster und NDB Cluster kann Port 4006 stattdessen als Multi-Write-Balanced-Verbindungen verwendet werden. Mit MaxScale haben Sie viele Optionen zur Auswahl, wenn Sie sich mit der Datenbank verbinden, wobei jede von ihnen ihre eigenen Vorteile bietet.
MaxScale-Clustering mit Docker Swarm
Mit Docker Swarm können wir eine Gruppe von MaxScale-Instanzen über den Swarm-Dienst mit mehr als einem Replikat zusammen mit Swarm Configs erstellen. Importieren Sie zunächst die Konfigurationsdatei in Swarm:
$ cat maxscale.conf | docker config create maxscale_config -
Bestätigen Sie mit:
$ docker config inspect --pretty maxscale_config
Erlauben Sie dann dem MaxScale-Datenbankbenutzer, sich von allen Swarm-Hosts im Netzwerk zu verbinden:
MariaDB> CREATE USER 'maxscale'@'192.168.0.%' IDENTIFIED BY 'my_s3cret';
MariaDB> GRANT ALL PRIVILEGES ON *.* TO [email protected]'192.168.0.%';
Beim Starten des Swarm-Dienstes für MaxScale können wir mehrere Container (Replikate genannt) erstellen, die wie unten beschrieben auf dieselbe Konfigurationsdatei abgebildet werden:
$ docker service create \
--name maxscale-cluster \
--replicas=3 \
--publish published=4008,target=4008 \
--publish published=4006,target=4006 \
--config source=maxscale_config,target=/etc/maxscale.cnf \
mariadb/maxscale
Das Obige erstellt drei MaxScale-Container, die über Swarm-Knoten verteilt sind. Bestätigen Sie mit:
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
yj6u2xcdj7lo maxscale-cluster replicated 3/3 mariadb/maxscale:latest *:4006->4006/tcp, *:4008->4008/tcp
Wenn die Anwendungen innerhalb des Swarm-Netzwerks laufen, können Sie einfach den Dienstnamen „maxscale-cluster“ als Datenbankhost für Ihre Anwendungen verwenden. Extern können Sie eine Verbindung zu jedem Docker-Host an den veröffentlichten Ports herstellen, und das Swarm-Netzwerk leitet die Verbindungen zu den richtigen Containern im Round-Robin-Verfahren weiter und gleicht sie aus. An dieser Stelle kann unsere Architektur wie folgt dargestellt werden:
Im zweiten Teil werden wir uns fortgeschrittene Anwendungsfälle von MaxScale auf Docker wie Dienststeuerung, Konfigurationsmanagement, Abfrageverarbeitung, Sicherheit und Cluster-Abgleich ansehen.