wall < "MySQL NDB Cluster Installation – in VirtualBox…"

Broadcast message from spillerm@unixe.de (pts/1) (Mo Mai 11 10:20:24 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.

Die kranke Idee

MySQL NDB Cluster Installation - Cluster "green"Wie einige von euch auf Twitter ja vielleicht schon am Rande mitbekommen haben beschäftige ich mich derzeit sehr intensiv mit MySQL-NDB-Cluster. Nachdem ich jetzt eine vergleichsweise lange Zeit mit der Theorie verbracht habe konnte ich inzwischen damit beginnen, ein wenig in die Praxis einzusteigen.

Das Produktivsystem werden zwei NDB-Cluster sein, die rechenzentrumsübergreifend eine Master-to-Master-Replikation fahren. Über virtuelle IPs wird die Verfügbarkeit realisiert — das System bleibt verfügbar, wenn einzelne Knoten ausfallen und sogar, wenn ein ganzer Standort ausfällt. Das greift in viele Bereiche ein und ist ein etwas umfangreicheres Projekt. Um ein Gefühl für die Sache zu bekommen, begann ich zu spielen: Cluster GREEN fand seinen Platz auf meinem MacPro, Cluster BLUE auf dem iMac und jeweils unter VirtualBox. DNS und DHCP laufen hier auf einem RaspberryPi.

Mein Beitrag erhebt keinen Anspruch auf Vollständigkeit, und insbesondere hafte ich nicht für eventuell entstehende Schäden; ich spiele meine Tutorials in aller Regel mehrfach durch, ehe ich sie veröffentliche, und das ist hier nun nicht anders — ich weise aber dennoch darauf hin, dass jeder für sich denken sollte, ehe ein Befehl in die Shell kopiert und ausgeführt wird — immer ;)

Und nun lasst uns beginnen…

Ein Grundsystem installieren

Das System soll unter dem aktuellen Ubuntu Server LTS laufen; zum Zeitpunkt der Erstellung des Artikels ist das die 14.04.2. Meine Idee ist, mir eine Installation als Basis zu erstellen und diese dann zu klonen, so dass ich nicht n-mal langweilige Installationsarbeit leisten muss. Auf die Details gehe ich an dieser Stelle mal nicht ein — es ist eine Standard-Installation von Ubuntu in VirtualBox auf einem 8GB VDI mit LVM, ohne home encryption und mit SSH, Netzwerk über NAT, Audio deaktiviert, kein Floppy, kein CD-ROM. Die Hardware-»Ausstattung« wird wie folgt sein (sollte sich jemand fragen, weshalb ich mit den 32GB RAM in meinem MacPro sehr glücklich bin: deshalb beispielsweise :D ):

  • zwei management nodes: 512MB RAM, 1x CPU
  • zwei data nodes: 2048MB RAM, 2x CPU

Hernach erledigen wir alle Schritte, die sowohl auf den management als auch auf den data nodes anfallen: Ordner erstellen, Updates und Pakete installieren; später werden wir noch das Netzwerk umkonfigurieren, denn DHCP ist für unsere Zwecke nicht so günstig, aber für den Moment ist es ganz angenehm, wenn die Kisten Verbindung nach aussen aufbauen können.

root@datanode1:~# apt-get update && apt-get upgrade
root@datanode1:~# apt-get install htop libaio1 libaio-dev munin-node
root@datanode1:~# mkdir /var/lib/mysql-cluster

Schon jetzt erstellen wir uns eine /etc/hosts, die für alle Hosts gelten wird:

## /etc/hosts
## IP           Hostname                Alias
127.0.0.1       localhost
10.0.2.10       lnv-10.intern           datanode1
10.0.2.11       lnv-11.intern           datanode2
10.0.2.20       lnv-20.intern           management1
10.0.2.21       lnv-21.intern           management2

Anschliessend muss das MySQL-Cluster-Paket (zum Zeitpunkt der Erstellung dieses Artikels 7.4.6) heruntergeladen und ausgepackt werden; wir schieben es direkt nach /usr/local.

root@datanode1:~# cd /usr/local
root@datanode1:/usr/local# wget https://dev.mysql.com/get/Downloads/MySQL-Cluster-7.4/mysql-cluster-gpl-7.4.6-linux-glibc2.5-x86_64.tar.gz
root@datanode1:/usr/local# tar xvfz mysql-cluster-gpl-7.4.6-linux-glibc2.5-x86_64.tar.gz
root@datanode1:/usr/local# rm mysql-cluster-gpl-7.4.6-linux-glibc2.5-x86_64.tar.gz

Jetzt kann die VM heruntergefahren und abgeschaltet werden: das Grundsystem ist fertig. Ich klone die Datenplatte — für das erste Management-System. Einfach nur kopieren ist nicht — beim Kopieren würde auch die UUID übernommen werden, so dass die neue Maschine nicht von der Platte würde booten können.

petzi:datanode1 spillerm$ VBoxManage clonevdi datanode1.vdi management1.vdi
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone hard disk created in format 'VDI'. UUID: cd612365-71ac-4cd1-8e1b-7b910a87e227

management nodes einrichten

management1

MySQL NDB Cluster InstallationIn VirtualBox wird jetzt eine neue Maschine angelegt (Einzelheiten siehe nebenstehenden Screenshot); dieser Maschine füttere ich das eben erstellte management1.vdi als Datenplatte ein und starte das System durch. Benötigt wird ausserdem eine config.iniGITHUB, in der die grundlegende Konfiguration unseres Clusters vorgenommen wird; sie liegt in /var/lib/mysql-cluster. Wir richten uns entsprechend ein:

root@management1# cd /usr/local/
root@management1# cp mysql-cluster-gpl-7.4.6-linux-glibc2.5-x86_64/bin/ndb_mgm* /usr/bin
root@management1# chmod 755 /usr/bin/ndb_mg*
root@management1# mkdir -p /usr/local/mysql/mysql-cluster
root@management1# rm -rf mysql-cluster-gpl-7.4.6-linux-glibc2.5-x86_64*
root@management1# echo "ndb_mgmd -f /var/lib/mysql-cluster/config.ini --configdir=/var/lib/mysql-cluster/" > /etc/init.d/ndb_mgmd && chmod 755 /etc/init.d/ndb_mgmd
root@management1# wget https://raw.githubusercontent.com/sysadmama/misc/master/mysql/config.ini -O /var/lib/mysql-cluster/config.ini

Abschliessend muss in /etc/hostname noch der Hostname geändert werden (von datanode1 auf management1) und wir bearbeiten die /etc/network/interfaces, so dass die IP fortan nicht mehr per DHCP bezogen, sondern statisch vergeben wird; Gateway und DNS werden nicht benötigt:

## /etc/network/interfaces
auto lo
iface lo inet loopback
 
auto eth0
iface eth0 inet static
    address 10.0.2.20
    netmask 255.255.255.0

management2

Die Maschine management1 ist nun soweit vorbereitet — sie kann heruntergefahren, abgeschaltet und geklont werden.

petzi:datanode1 spillerm$ VBoxManage clonevdi management1.vdi management2.vdi
0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Clone hard disk created in format 'VDI'. UUID: 2e91831c-238b-48be-b66a-338b482b02c3

Der Host management2 wird in VirtualBox analog zu management1 eingerichtet, die Datenplatte management2.vdi wird ihm untergeschoben und er wird hochgefahren. Hier muss nur in /etc/hostname der Hostname geändert werden (von management1 auf management2) und in /etc/network/interfaces die IP-Adresse (von 10.0.2.20 auf 10.0.2.21). Ausserdem muss in /etc/mysql-proxy.conf die proxy-address angepasst werden!

Zur Sicherheit sollten nun beide management nodes einmal sauber durchgestartet werden — Netzwerk-Adapter 1 habe ich hierbei auf Internal network gesetzt, Netzwerk-Adapter 2 hingegen auf Bridged network — in meinem Fall über das WLAN-Interface des iMac. So bieten die management nodes »nach innen« ein Interface mit einer Adresse aus dem 10.0.2.x-Netzwerk, »nach aussen« erhalten sie eine Adresse aus meinem regulären 192.168.2.x-Netzwerk, die über meinen DHCP fest vergeben wird. Zu beachten ist, dass hierfür auf beiden management nodes die /etc/network/interfaces um eth1 erweitert werden muss:

...
auto eth1
iface eth1 inet dhcp

Inbetriebnahme der management nodes

management1

root@management1:~# /etc/init.d/ndb_mgmd start
MySQL Cluster Management Server mysql-5.6.24 ndb-7.4.6
root@management1:~# ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm> show
Connected to Management Server at: localhost:1186
ERROR Message: The cluster configuration is not yet confirmed by all defined management servers.
This management server is still waiting for node 2 to connect.

Das ist doch mal eine klare Ansage. Nun denn: starten wir auf die gleiche Weise den Dienst auf management2!

management2

root@management2:~# /etc/init.d/ndb_mgmd start
MySQL Cluster Management Server mysql-5.6.24 ndb-7.4.6
root@management1:~# ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm> show
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=3 (not connected, accepting connect from datanode1)
id=4 (not connected, accepting connect from datanode2)
 
[ndb_mgmd(MGM)]	2 node(s)
id=1	@10.0.2.20  (mysql-5.6.24 ndb-7.4.6)
id=2	@10.0.2.21  (mysql-5.6.24 ndb-7.4.6)
 
[mysqld(API)]	2 node(s)
id=5 (not connected, accepting connect from any host)
id=6 (not connected, accepting connect from any host)

Wunderbar, beide management nodes sind up and running. Der Rest erwartungsgemäss nicht — die müssen wir ja nun aufziehen. Wir beenden die Arbeiten an den management nodes, indem wir abschliessend noch auf beiden Nodes dafür sorgen, dass /etc/init.d/ndb_mgmd beim Booten ausgeführt wird.

root@management1:/usr/local# update-rc.d ndb_mgmd defaults
update-rc.d: warning: /etc/init.d/ndb_mgmd missing LSB information
update-rc.d: see <http://wiki.debian.org/LSBInitScripts>
 Adding system startup for /etc/init.d/ndb_mgmd ...
   /etc/rc0.d/K20ndb_mgmd -> ../init.d/ndb_mgmd
   /etc/rc1.d/K20ndb_mgmd -> ../init.d/ndb_mgmd
   /etc/rc6.d/K20ndb_mgmd -> ../init.d/ndb_mgmd
   /etc/rc2.d/S20ndb_mgmd -> ../init.d/ndb_mgmd
   /etc/rc3.d/S20ndb_mgmd -> ../init.d/ndb_mgmd
   /etc/rc4.d/S20ndb_mgmd -> ../init.d/ndb_mgmd
   /etc/rc5.d/S20ndb_mgmd -> ../init.d/ndb_mgmd

Die data nodes einrichten

Hierzu starten wir unsere datanode1 wieder; das Netzwerk belassen wir noch auf NAT, damit wir bequemerweise die Konfigurationsdateien aus dem Netz ziehen können. Wir müssen Binaries an Ort und Stelle bewegen, Startscripte erstellen, alles einrichten. Die data nodes benötigen eine my.cnfGITHUB in /etc; sollte es bereits einen Ordner /etc/mysql geben, so ist man gut beraten, diesen umzubenennen, da er zu Konflikten führen kann. Und natürlich muss die bind-address gegebenenfalls angepasst werden!

root@datanode1:~# groupadd mysql
root@datanode1:~# useradd -g mysql mysql
root@datanode1:~# wget https://raw.githubusercontent.com/sysadmama/misc/master/mysql/my.cnf -O /etc/my.cnf
root@datanode1:~# cd /usr/local
root@datanode1:/usr/local# ln -s mysql-cluster-gpl-7.4.6-linux-glibc2.5-x86_64 mysql
root@datanode1:/usr/local# cd mysql
root@datanode1:/usr/local/mysql# mkdir /usr/share/mysql
root@datanode1:/usr/local/mysql# cp share/english/errmsg.sys /usr/share/mysql/
root@datanode1:/usr/local/mysql# mv bin/* /usr/bin
root@datanode1:/usr/local/mysql# rmdir bin/
root@datanode1:/usr/local/mysql# ln -s /usr/bin .
root@datanode1:/usr/local/mysql# scripts/mysql_install_db --user=mysql --basedir=.
Installing MySQL system tables...
[...]
root@datanode1:/usr/local/mysql# chown -R root:mysql .
root@datanode1:/usr/local/mysql# chown -R mysql data/
root@datanode1:/usr/local/mysql# cp support-files/mysql.server /etc/init.d/
root@datanode1:/usr/local/mysql# chmod 755 /etc/init.d/mysql.server

An dieser Stelle würde ich empfehlen, die VM herunterzufahren, abzuschalten und wiederum zu klonen — zu datanode2. Wie gehabt: in VirtualBox eine neue VM datanode2 anlegen, datanode2.vdi als Datenplatte einfüttern, booten. Den Hostnamen anpassen, die IP — wie bei den management nodes fest vergeben. Ob ihr die Maschine dann rebootet oder von Hand umsetzt sei euch überlassen — jedenfalls können nun datanode1 und datanode2 gestartet werden, wiederum beide mit internem Netz statt NAT. Und nun wird es spannend: wir können initialisieren und dann unsere Dienste starten. Die Initialisierung muss nur dann gemacht werden, wenn

  • der Node das erste Mal gestartet wird oder
  • wenn die config.ini auf den management nodes geändert wurde

datanode1 initialisieren

root@datanode1:~# cd /var/lib/mysql-cluster
root@datanode1:/var/lib/mysql-cluster# ndbd --initial
2015-05-05 21:26:29 [ndbd] INFO     -- Angel connected to '10.0.2.20:1186'
2015-05-05 21:26:29 [ndbd] INFO     -- Angel allocated nodeid: 3

Dann mal spicken auf einem der management server (ja, es ist egal, welcher von beiden genutzt wird):

ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=3	@10.0.2.10  (mysql-5.6.23 ndb-7.4.4, starting, Nodegroup: 0)
id=4 (not connected, accepting connect from 10.0.2.11)
 
[ndb_mgmd(MGM)]	2 node(s)
id=1	@10.0.2.20  (mysql-5.6.23 ndb-7.4.4)
id=2	@10.0.2.21  (mysql-5.6.23 ndb-7.4.4)
 
[mysqld(API)]	2 node(s)
id=5 (not connected, accepting connect from any host)
id=6 (not connected, accepting connect from any host)

datanode2 initialisieren

root@datanode2:/var/lib/mysql-cluster# ndbd --initial
2015-05-05 21:39:55 [ndbd] INFO     -- Angel connected to '10.0.2.21:1186'
2015-05-05 21:39:55 [ndbd] INFO     -- Angel allocated nodeid: 4
ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=3	@10.0.2.10  (mysql-5.6.24 ndb-7.4.6, starting, Nodegroup: 0, *)
id=4	@10.0.2.11  (mysql-5.6.24 ndb-7.4.6, starting, Nodegroup: 0)
 
[ndb_mgmd(MGM)]	2 node(s)
id=1	@10.0.2.20  (mysql-5.6.24 ndb-7.4.6)
id=2	@10.0.2.21  (mysql-5.6.24 ndb-7.4.6)
 
[mysqld(API)]	2 node(s)
id=5 (not connected, accepting connect from any host)
id=6 (not connected, accepting connect from any host)

mysql.server und secure_installation auf beiden data nodes

# /etc/init.d/mysql.server start
.............................*
root@datanode1:~# /usr/local/mysql/bin/mysql_secure_installation
[...]
Set root password? [Y/n]
[...]
Remove anonymous users? [Y/n]
[...]
Disallow root login remotely? [Y/n]
[...]
Remove test database and access to it? [Y/n] n
[...]
Reload privilege tables now? [Y/n] Y
[...]
Cleaning up...

MySQL-NDB-Cluster ist nun up & running.

ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]	2 node(s)
id=3	@10.0.2.10  (mysql-5.6.24 ndb-7.4.6, Nodegroup: 0, *)
id=4	@10.0.2.11  (mysql-5.6.24 ndb-7.4.6, Nodegroup: 0)
 
[ndb_mgmd(MGM)]	2 node(s)
id=1	@10.0.2.20  (mysql-5.6.24 ndb-7.4.6)
id=2	@10.0.2.21  (mysql-5.6.24 ndb-7.4.6)
 
[mysqld(API)]	2 node(s)
id=5	@10.0.2.10  (mysql-5.6.24 ndb-7.4.6)
id=6	@10.0.2.11  (mysql-5.6.24 ndb-7.4.6)

Grossartig! Abschliessend sorgen wir noch dafür, dass ndbd und mysql.server beim Booten automatisch gestartet werden — wiederum auf beiden data nodes. Hierzu habe ich den Aufruf /usr/bin/ndbd einfach in die /etc/rc.local geschrieben (vor das exit 0!) und mysql.server als Startscript hinzugefügt.

# update-rc.d mysql.server defaults
[...]

MySQL NDB Cluster InstallationDas ist die Basis: von hier aus gehen wir weiter. Die nächsten Schritte verpacke ich der Übersichtlichkeit halber in eigene Artikel, denn wie ihr seht: es entsteht ein ganz schöner Overhead. (Der nächste Schritt in meinem Cluster besteht in Distributed Privileges.) Mein MacPro langweilt sich vergleichsweise — mal sehen, ob das so bleibt… ;) Marianne

Mögliche Fehler

Forced node shutdown completed

Fehler : Node 4: Forced node shutdown completed.
Occured during startphase 0. Initiated by signal 9.

Lag in meinem Fall daran, dass meine data nodes gnadenlos zu wenig RAM hatten (zum Testen hatte ich es mit 512MB versucht, die Systeme belegen im Leerlauf aber schon 1GB); Ubuntu packte darauf hin sozusagen seine Prozess-Fliegenklatsche (OOM Killer) aus und erschlug wahllos Prozesse. Lässt sich beispielsweise per dmesg gut nachvollziehen.

No such file or directory

Das passiert beispielsweise, wenn man die 32bit-Binaries auf ein 64bit-System packt und ndb_mgmd zu starten versucht: das Binary ist da, und dennoch behauptet das System No such file or directory. Mittels file /usr/bin/ndb_mgmd lässt sich der Fehler beispielsweise recht schnell eingrenzen… Kommt davon, wenn man beim Download pennt… ;)

Failed to allocate nodeid

Failed to allocate nodeid, error: 'Error:
  Could not alloc node id at management1 port 1186: No free node id found for ndbd(NDB).'

Diese Meldung erscheint zum Beispiel, wenn man auf einem der data nodes einen ndbd starten möchte, er jedoch schon läuft…

4