mysql-proxy und DNS-Round-Robin
Weitere Beiträge der Artikelserie „MySQL NDB Cluster“ findest du an dieser Stelle.
Eine einfache Lastverteilung auf meinem MySQL-NDB-Cluster möchte ich mittels mysql-proxy umsetzen; ein schmales Paket, das jedoch genau das tut, was ich haben möchte. Ich installiere es auf beiden Management Nodes. Darüber hinaus benötigen wir für die Konfiguration des Dienstes eine mysql-proxy.conf, die wir nach /etc
schieben und chmod 0600 setzen
(!), sowie eine mysql-proxy, die ihren Platz in /etc/default
findet.
$ apt-get install mysql-proxy
$ wget https://raw.githubusercontent.com/netzwerkgoettin/misc/master/mysql/mysql-proxy -O /etc/default/mysql-proxy
$ wget https://raw.githubusercontent.com/netzwerkgoettin/misc/master/mysql/mysql-proxy.conf -O /etc/mysql-proxy.conf
$ chmod 0600 /etc/mysql-proxy.conf
Im ersten Artikel zu dem Thema hatte ich bereits einen Grundstein für dieses Setup gelegt: auf allen Data Nodes wurde dem mysql.server
jeweils seine bind-address
in der /etc/my.cnf
mitgegeben, so dass der Dienst auf Port 3306 der bind-address
zu erreichen ist. Auf dieses Feature ist mysql-proxy
angewiesen: er läuft auf den Management Nodes seinerseits auf Port 3306 (proxy-address
in /etc/mysql-proxy.conf
) und stellt bei Anfragen die Verbindung zu den Data Nodes her; diese proxy-address
muss natürlich die von außen erreichbare sein, denn auf sie sollen sich unsere Clients ja späterhin verbinden können:
-
management1
: proxy-address = 192.168.2.13:3306 -
management2
: proxy-address = 192.168.2.14:3306
Und nun kann – wiederum auf beiden Management Nodes – der Dienst gestartet werden. Ein schüchterner Blick ins Logfile verrät uns bestenfalls, dass alles läuft :
root@management1:~# /etc/init.d/mysql-proxy start
[...]
2015-05-07 13:58:35: (message) mysql-proxy 0.8.1 started
2015-05-07 13:58:35: (debug) max open file-descriptors = 1024
2015-05-07 13:58:35: (message) proxy listening on port 192.168.2.13:3306
2015-05-07 13:58:35: (message) added read/write backend: 10.0.2.10:3306
2015-05-07 13:58:35: (message) added read/write backend: 10.0.2.11:3306
Yes! Das ist genau das, was wir haben wollten – beide Data Nodes sind als Backend registriert, und die anfallende Last wird gleichmäßig zwischen beiden verteilt – und das von beiden Management Nodes aus. Konfigurieren wir nun unsere Anwendungen, können wir beispielsweise green1.intern
als DB-Host angeben, das würde management1
entsprechen; charmanter wäre es allerdings, ganz global ein mysql.intern
zu definieren und darunter alle Management Nodes zusammenzufassen.
Diese Lösung hat ihre Schwächen, das ist klar; beim sogenannten DNS Round Robin werden nacheinander alle A-Records für einen Eintrag abgeklappert – unabhängig davon, ob die nun gerade erreichbar sind oder nicht, die Namensauflösung wird zuerst gemacht. Antwortet der Host dann nicht, läuft der Request ins Leere. Unschön, aber irgendwann muss man auf der Spielwiese ja auch mal eine Grenze ziehen (Download der graphischen Darstellung als PDF) :D Für ein Produktivsystem würde ich eine andere Lösung erarbeiten. In meinem bind
habe ich mir fürs erste einfach die entsprechenden A-Records gesetzt:
;; mysql cluster
mysql IN A 192.168.2.13
IN A 192.168.2.14
Sobald auf beiden Management Nodes der Dienst mysql-proxy
gestartet ist, können fröhliche ping
-Versuche auf mysql.intern
gestartet werden… Bei mir funktionierte es auf Anhieb, mal antwortete ein Host, mal der andere. Versuchen wir nun, uns auf Port 3306 zu verbinden:
root@pelle:/etc/bind# telnet mysql.intern 3306
Trying 192.168.2.13...
Connected to mysql.intern.
Escape character is '^]'.
DHost 'management1' is not allowed to connect to this MySQL serverConnection closed by foreign host.
Sauber! Unser Cluster antwortet – es lehnt die Verbindung zwar ab, aber er antwortet :D Was wir nun tun müssen ist, einen entsprechenden Proxy-User anzulegen, dem es erlaubt ist, sich zu verbinden. Machen wir das mal so:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.6.24-ndb-7.4.6-cluster-gpl MySQL Cluster Community Server (GPL)
...
mysql> CREATE USER 'proxy'@'10.0.2.%'
-> IDENTIFIED BY 'nLj8eShazP6I';
Query OK, 0 rows affected (0.01 sec)
mysql> FLUSH PRIVILEGES
Query OK, 0 rows affected (0.00 sec)
Hierbei ist zu beachten, dass der User auf allen angeschlossenen data nodes verfügbar sein muss; entweder muss er also überall manuell angelegt werden, oder aber wir haben für eine Verteilung der Daten gesorgt. Und wie gestaltet sich ein neuerlicher Verbindungsversuch?
root@pelle:/etc/bind# telnet mysql 3306
Trying 192.168.2.14...
Connected to mysql.intern.
Escape character is '^]'.
J
5.6.24-ndb-7.4.6-cluster-gplNP&mu#L4?`e\{xgzPb{c_
Das ist der Punkt, an dem ich management1
noch ein munin
und allen anderen ein munin-node
verpasse, um das Verhalten der Kisten beobachten zu können, denn dann wird es spannend: es können testweise die ersten Datenbanken in das System hineingefüttert werden…
Hintergrundbild: Bild genauer anschauen – © Marianne Spiller – Alle Rechte vorbehalten