MySQL NDB Cluster Installation - in VirtualBox
- Die kranke Idee
- Ein Grundsystem installieren
- Management Nodes einrichten
- Inbetriebnahme der Management Nodes
- Die Data Nodes einrichten
- Mögliche Fehler
Weitere Beiträge der Artikelserie „MySQL NDB Cluster“ findest du an dieser Stelle.
Die kranke Idee
Wie einige von euch auf Ex-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.
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 außen 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:
## file: "/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
Anschließend 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
In VirtualBox wird jetzt eine neue Maschine angelegt; dieser Maschine füttere ich das eben erstellte management1.vdi
als Datenplatte ein und starte das System durch. Benötigt wird außerdem eine config.ini, 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/netzwerkgoettin/misc/master/mysql/config.ini -O /var/lib/mysql-cluster/config.ini
Abschließend 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:
## file: "/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). Außerdem 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 außen“ 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&running. Der Rest erwartungsgemäß nicht – die müssen wir ja nun aufziehen. Wir beenden die Arbeiten an den management nodes, indem wir abschließend 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
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.cnf 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/netzwerkgoettin/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 Node (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)
Großartig! Abschließend 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
Das 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… ;)
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…
Hintergrundbild: Bild genauer anschauen – © Marianne Spiller – Alle Rechte vorbehalten