wall < "mysql-proxy und DNS-Round-Robin"

Broadcast message from spillerm@unixe.de (pts/1) (Mi Mai 13 10:31:17 2015):
4
Diesen Beitrag schrieb ich vor 4 Jahren. Behalte das beim Lesen bitte im Hinterkopf.

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.confGITHUB, die wir nach /etc schieben und chmod 0600 setzen (!), sowie eine mysql-proxyGITHUB, die ihren Platz in /etc/default findet.

# apt-get install mysql-proxy
# wget https://raw.githubusercontent.com/sysadmama/misc/master/mysql/mysql-proxy -O /etc/default/mysql-proxy
# wget https://raw.githubusercontent.com/sysadmama/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 aussen 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ässig 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.

Grafische Darstellung des experimentellen MySQL NDB Clusters auf dem Mac Pro und mysql-proxy 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 PDFGITHUB) :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:

root@datanode2:~# mysql -u root -p
<pre lang="mysql">Enter password:
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_

MarianneDas 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

4