Wie man ein Load-Balanced MySQL Cluster einrichtet

Version 1.0
Author: Falko Timme <ft [at] falkotimme [dot] com>

Diese Anleitung veranschaulicht, wie man ein MySQL 5 Cluster mit drei Systemen konfiguriert: zwei Speicher-Systeme und ein Management-System. Die Lastverteilung dieses Clusters wird von einem hoch-verfügbaren Load Balancer übernommen, der tatsächlich zwei Systeme hat, die das Ultra Monkey Paket verwenden, welches heartbeat (um zu überprüfen, ob das andere System noch funktionstüchtig ist) und ldirectord (um die Anfragen an die Systeme des MySQL Clusters aufzusplitten) bereitstellt.

In dieser Anleitung verwende ich Debian Sarge für alle Systeme. Daher kann das Setup für andere Distributionen etwas anders aussehen. Die MySQL Version, die ich in diesem Setup verwende, ist die Version 5.0.19. Wenn Du MySQL 5 nicht verwenden möchtest, kannst Du auch MySQL 4.1 verwenden, obwohl ich dies nicht getestet habe.

Diese Anleitung ist ein praktischer Leitfaden; theoretisches Hintergrundwissen wird nicht abgedeckt. Dies wird in zahlreichen anderen Dokumenten im Netz behandelt.

Diese Anleitung ist ohne jegliche Gewähr! Ich möchte darauf hinweisen, dass dies nicht der einzige Weg ist, ein solches System einzurichten. Es gibt viele Möglichkeiten dieses Ziel zu erreichen – dies ist der Weg, den ich gwählt habe. Ich übernehme keine Garantie, dass dies auch bei Dir funktioniert!

1 Meine Server

Ich verwende folgende Debian Server, die sich alle im gleichen Netzwerk befinden (192.168.0.x in diesem Beispiel):

  • sql1.example.com: 192.168.0.101 MySQL Cluster System 1
  • sql2.example.com: 192.168.0.102 MySQL Cluster System 2
  • loadb1.example.com: 192.168.0.103 Load Balancer 1 / MySQL Cluster Management Server
  • loadb2.example.com: 192.168.0.104 Load Balancer 2

Außerdem benötigen wir eine virtuelle IP Adresse : 192.168.0.105. Sie wird vom Load Balancer dem MySQL Cluster zugewiesen, so dass Anwendungen eine einzige IP Adresse haben, um auf das Cluster zugreifen zu können.

Obwohl wir zwei MySQL Cluster Systeme in unserem MySQL Cluster haben wollen, brauchen wir dennoch ein drittes System, den MySQL Cluster Management Server, hauptsächlich aus einem Grund: Falls eines der beiden MySQL Cluster Systeme ausfällt und der Management Server nicht läuft, werden die Daten auf den beidne Cluster Systemen inkonsistent („split brain“). Außerdem brauchen wir ihn, um das MySQL Cluster konfigurieren zu können.

Also brauchen wir eigentlich fünf Maschinen für unser Setup:

2 MySQL cluster nodes + 1 cluster management server + 2 Load Balancers = 5

Da der MySQL Cluster Management Server nicht viele Ressourcen verwendet und das System sonst gar nichts tunt würde, können wir unseren ersten Load Balancer auf diese Maschine setzen, was uns eine Maschine spart, also haben wir am Ende vier Maschinen.

2 Den MySQL Cluster Management Server aufsetzen

Zuerst müssen wir MySQL 5.0.19 (die max Version!) runter laden und den Cluster Management Server (ndb_mgmd) und den Cluster Management Client (ndb_mgm – er kann verwendet werden, um die Vorgänge im Cluster zu überwachen) installieren. Folgende Schritte werden auf loadb1.example.com (192.168.0.103) ausgeführt:

loadb1.example.com:

mkdir /usr/src/mysql-mgm
cd /usr/src/mysql-mgm
wget http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-max-5.0.19-linux-i686-
glibc23.tar.gz/from/http://www.mirrorservice.org/sites/ftp.mysql.com/
tar xvfz mysql-max-5.0.19-linux-i686-glibc23.tar.gz
cd mysql-max-5.0.19-linux-i686-glibc23
mv bin/ndb_mgm /usr/bin
mv bin/ndb_mgmd /usr/bin
chmod 755 /usr/bin/ndb_mg*
cd /usr/src
rm -rf /usr/src/mysql-mgm

Als Nächstes müssen wir die Cluster Konfigurationsdatei /var/lib/mysql-cluster/config.ini erstellen:

loadb1.example.com:

mkdir /var/lib/mysql-cluster
cd /var/lib/mysql-cluster
vi config.ini

[NDBD DEFAULT]
NoOfReplicas=2

[MYSQLD DEFAULT]

[NDB_MGMD DEFAULT]

[TCP DEFAULT]

# Section for the cluster management node
[NDB_MGMD]
# IP address of the management node (this system)
HostName=192.168.0.103

# Section for the storage nodes
[NDBD]
# IP address of the first storage node
HostName=192.168.0.101
DataDir= /var/lib/mysql-cluster

[NDBD]
# IP address of the second storage node
HostName=192.168.0.102
DataDir=/var/lib/mysql-cluster

# one [MYSQLD] per storage node
[MYSQLD]
[MYSQLD]

Bitte ersetze die IP Adressen in der Datei entsprechend.

Dann starten wir den Cluster Management Server:

loadb1.example.com:

ndb_mgmd -f /var/lib/mysql-cluster/config.ini

Es macht Sinn den Management Server automatisch beim Hochfahren starten zu lassen, also erstellen wir ein ganz einfaches Init Slript und die entsprechenden Startup Links:

loadb1.example.com:

echo ’ndb_mgmd -f /var/lib/mysql-cluster/config.ini‘ > /etc/init.d/ndb_mgmd
chmod 755 /etc/init.d/ndb_mgmd
update-rc.d ndb_mgmd defaults

3 Die MySQL Cluster Systeme (Speicher-Systeme) aufsetzen

Nun installieren wir mysql-max-5.0.19 auf sql1.example.com und sql2.example.com:

sql1.example.com / sql2.example.com:

groupadd mysql
useradd -g mysql mysql
cd /usr/local/
wget http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-max-5.0.19-linux-i686-
glibc23.tar.gz/from/http://www.mirrorservice.org/sites/ftp.mysql.com/
tar xvfz mysql-max-5.0.19-linux-i686-glibc23.tar.gz
ln -s mysql-max-5.0.19-linux-i686-glibc23 mysql
cd mysql
scripts/mysql_install_db –user=mysql
chown -R root:mysql .
chown -R mysql data
cp support-files/mysql.server /etc/init.d/
chmod 755 /etc/init.d/mysql.server
update-rc.d mysql.server defaults
cd /usr/local/mysql/bin
mv * /usr/bin
cd ../
rm -fr /usr/local/mysql/bin
ln -s /usr/bin /usr/local/mysql/bin

Dann erstellen wir die MySQL Konfigurationsdatei /etc/my.cnf auf beiden Systemen:

sql1.example.com / sql2.example.com:

vi /etc/my.cnf

[mysqld]
ndbcluster
# IP address of the cluster management node
ndb-connectstring=192.168.0.103

[mysql_cluster]
# IP address of the cluster management node
ndb-connectstring=192.168.0.103

Gib Acht, dass Du die korrekte IP Adresse des MySQL Cluster Management Servers eingibst.

Als Nächstes erstellen wir die Daten-Verzeichnisse und starten den MySQL Server auf beiden Cluster Systemen:

sql1.example.com / sql2.example.com:

mkdir /var/lib/mysql-cluster
cd /var/lib/mysql-cluster
ndbd –initial
/etc/init.d/mysql.server start

(Bitte beachte: wir brauchen ndbd –initial nur dann ausführen, wenn MySQL erstmalig gestartet wird und sich /var/lib/mysql-cluster/config.ini auf loadb1.example.com ändert.)

Nun können wir ein Passwort für den MySQL Root-Benutzer einrichten:

sql1.example.com / sql2.example.com:

mysqladmin -u root password yourrootsqlpassword

Wir möchten die Cluster Systeme beim Hochfahren starten, also erstellen wir ein ndbd Init Skript und die entsprechenden System Startup Links:

sql1.example.com / sql2.example.com:

echo ’ndbd‘ > /etc/init.d/ndbd
chmod 755 /etc/init.d/ndbd
update-rc.d ndbd defaults

4 Das MySQL Cluster testen

Unsere MySQL Cluster Konfiguration ist fast abgeschlossen. Nun ist es an der Zeit sie zu testen. Führe auf dem Cluster Management Server (loadb1.example.com) den Cluster Management Client ndb_mgm aus um zu überprüfen, ob die Cluster Systeme verbunden sind:

loadb1.example.com:

ndb_mgm

Du solltest Folgendes sehen:

-- NDB Cluster -- Management Client --
ndb_mgm>

Tippe nun show; bei der Befehlaufforderung:

show;

Die Ausgabe sollte wie folgt sein:

ndb_mgm> show;
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)] 2 node(s)
id=2 @192.168.0.101 (Version: 5.0.19, Nodegroup: 0, Master)
id=3 @192.168.0.102 (Version: 5.0.19, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.0.103 (Version: 5.0.19)

[mysqld(API)] 2 node(s)
id=4 @192.168.0.101 (Version: 5.0.19)
id=5 @192.168.0.102 (Version: 5.0.19)

ndb_mgm>

Wenn Du siehst, dass Deine Systeme verbunden sind, dann ist alles in Ordnung!

Gib Folgendes ein

quit;

um die ndb_mgm Client Console zu verlassen.

Nun erstellen wir eine Test-Datenbank mit einer Test-Tabelle und einigen Daten auf sql1.example.com:

sql1.example.com:

mysql -u root -p
CREATE DATABASE mysqlclustertest;
USE mysqlclustertest;
CREATE TABLE testtable (i INT) ENGINE=NDBCLUSTER;
INSERT INTO testtable () VALUES (1);
SELECT * FROM testtable;
quit;

(Sieh Dir das CREATE Statment an: Wir müssen  ENGINE=NDBCLUSTER für alle Datenbanktabellen verwenden, die geclustert werden sollen! Wenn Du einen anderen Engine verwendest, dann wird das Clustern nicht funktionieren!)

Das Ergebnis des SELECT Statements sollte sein:

mysql> SELECT * FROM testtable;
+------+
| i    |
+------+
| 1    |
+------+
1 row in set (0.03 sec)

Nun erstellen wir die gleiche Datenbank auf sql2.example.com (ja, wir müssen sie erstellen, aber danach sollte testtable und deren Daten auf sql2.example.com repliziert werden, da testtable  ENGINE=NDBCLUSTER verwendet):

sql2.example.com:

mysql -u root -p
CREATE DATABASE mysqlclustertest;
USE mysqlclustertest;
SELECT * FROM testtable;

Das SELECT Statement sollte Dir das gleiche Ergebnis wie zuvor auf sql1.example.com anzeigen:

mysql> SELECT * FROM testtable;
+------+
| i    |
+------+
| 1    |
+------+
1 row in set (0.04 sec)

Als wurden die Daten von sql1.example.com auf sql2.example.com repliziert. Nun fügen wir eine weitere Reihe in testtable ein:

sql2.example.com:

INSERT INTO testtable () VALUES (2);
quit;

Lass uns nun zurück zu sql1.example.com gehen und überprüfen, ob wir die neue Reihe dort sehen:

sql1.example.com:

mysql -u root -p
USE mysqlclustertest;
SELECT * FROM testtable;
quit;

Du solltest etwas in der Art sehen:

mysql> SELECT * FROM testtable;
+------+
| i    |
+------+
| 1    |
| 2    |
+------+
2 rows in set (0.05 sec)

Somit haben beide MySQL Cluster Systeme immer die gleichen Daten!

Lass uns nun herausfinden was passiert, wenn wir System 1 (sql1.example.com) anhalten: Führe dies aus

sql1.example.com:

killall ndbd

und prüfe mit

ps aux | grep ndbd | grep -iv grep

ob alle ndbd Prozesse beendet wurden. Wenn Du immer noch ndbd Prozesse sehen kannst, führe erneut dies aus

killall ndbd

bis alle ndbd Prozesse verschwunden sind.

Lass uns nun den Cluster Status auf unserem Management Server (loadb1.example.com) überprüfen:

loadb1.example.com:

ndb_mgm

Erteile auf der ndb_mgm Console diesen Befehl

show;

und Du müsstest Folgendes sehen können:

ndb_mgm> show;
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)] 2 node(s)
id=2 (not connected, accepting connect from 192.168.0.101)
id=3 @192.168.0.102 (Version: 5.0.19, Nodegroup: 0, Master)

[ndb_mgmd(MGM)] 1 node(s)
id=1 @192.168.0.103 (Version: 5.0.19)

[mysqld(API)] 2 node(s)
id=4 @192.168.0.101 (Version: 5.0.19)
id=5 @192.168.0.102 (Version: 5.0.19)

ndb_mgm>

Wie Du siehst ist sql1.example.com nicht mehr verbunden.

Gib dies ein

quit;

um die ndb_mgm Console zu verlassen.

Lass uns nun  sql2.example.com überprüfen:

sql2.example.com:

mysql -u root -p
USE mysqlclustertest;
SELECT * FROM testtable;
quit;

Das Ergebnis der SELECT Anfrage sollte immer noch dies sein

mysql> SELECT * FROM testtable;
+------+
| i    |
+------+
| 1    |
| 2    |
+------+
2 rows in set (0.17 sec)

Ok, alle Tests liefen gut, also lass uns nun unser sql1.example.com System starten:

sql1.example.com:

ndbd

5 Wie man das Cluster neu startet

Lass uns nun davon ausgehen, dass Du das MySQL Cluster neu starten möchtest, weil Du zum Beispiel /var/lib/mysql-cluster/config.ini auf loadb1.example.com geändert hast oder auch aus einem anderen Grund. Um dies auszuführen, verwendest Du den ndb_mgm Cluster Management Client auf loadb1.example.com:

loadb1.example.com:

ndb_mgm

Auf der ndb_mgm Console gib dies ein

shutdown;

Dann siehst Du etwas in der Art:

ndb_mgm> shutdown;
Node 3: Cluster shutdown initiated
Node 2: Node shutdown completed.
2 NDB Cluster node(s) have shutdown.
NDB Cluster management server shutdown.
ndb_mgm>

Das bedeutet, dass die Cluster Systeme sql1.example.com und sql2.example.com und auch der Cluster Management Server runter gefahren sind.

Führe dies aus

quit;

um die ndb_mgm Console zu verlassen.

Um den Cluster Management Server zu starten, führe dies sowohl auf loadb1.example.com aus:

loadb1.example.com:

ndb_mgmd -f /var/lib/mysql-cluster/config.ini

und auf sql1.example.com und sql2.example.com führst Du dies aus

sql1.example.com / sql2.example.com:

ndbd

oder, wenn Du /var/lib/mysql-cluster/config.ini auf loadb1.example.com geändert hast:

ndbd –initial

Danach kannst Du auf loadb1.example.com überprüfen, ob das Cluster neu gestartet ist:

loadb1.example.com:

ndb_mgm

Gib auf der ndb_mgm Console dies ein

show;

um den derzeitigen Status  des Clusters sehen zu können. Es kann nach einem Neustart ein paar Sekunden dauern bis aller alle Systeme angeben, dass sie verbunden sind.

Gib Folendes ein

quit;

um die  ndb_mgm Console zu verlassen.

6 Konfiguration des Load Balancers

Unser MySQL Cluster ist nun fertig und Du könntest es nun verwenden. Jedoch haben wir keine einzige IP Adresse, die wir nutzen könnten, um auf das Cluster zugreifen zu können, was bedeutet, dass Du Deine Anwendungen so konfigurieren musst, dass ein Teil das MySQL Cluster System 1 (sql1.example.com) und der Rest das andere System (sql2.example.com) verwendet. Natürlich könnten all Deine Anwendungen auch nur ein System verwenden, aber was bringt es dann ein Cluster zu haben, wenn Du die Last nicht zwischen den Cluster Systemen aufteilst? Ein weiteres Problem: Was passiert wenn eines der Cluster Systeme ausfällts? Dann funktionieren die Anwendungen, die dieses Cluster System verwenden, nicht mehr.

Die Lösung ist ein Load Balancer vor dem MySQL Cluster, der (wie sein Name schon sagt) die Last zwischen den MySQL Cluster Systemen balanciert. Der Load Blanacer konfiguriert eine virtuelle IP Adresse, die zwischen den Cluster Systemen aufgeteilt wird. Alle Deine Anwendungen verwenden diese virtuelle IP Adresse um auf das Cluster zugreifen zu können. Wenn eines der Systeme ausfällt, dann werden Deine Anwendungen trotzdem funktionieren, da der Load Balancer  die Anfragen an das funktionstüchtige System weiter leitet.

In diesem Szenario wird der Load Balancer zum Flaschenhals. Was passiert, wenn der Load Balancer ausfällt? Dazu werdne wir zwei Load Balancer (loadb1.example.com und loadb2.example.com) in einem aktiven/passiven Setup konfigurieren, was bedeutet, dass wir einen aktiven Load Balancer und einen hot-standby Load Balancer haben. Der Letztere wird dann aktiv, wenn der aktive ausfällt. Beide Load Balancer verwenden heartbeat um zu überprüfen, ob der andere Load Balancer noch funktioniert. Sie verwenden beide ldirectord, den eigentlichen Load Balancer, der die Last auf die Cluster Systeme verteilt. heartbeat und ldirectord werden vom Ultra Monkey Paket bereitgestellt, das wir installieren werden.

Es ist wichtig, dass loadb1.example.com und loadb2.example.com  IPVS (IP Virtual Server) in ihren Kernels unterstützen. IPVS implementiert transport-layer Load Balancing innerhalb des Linux Kernels.

6.1 Installation von Ultra Monkey

Ok, lass uns anfangen: zuerst aktivieren wir IPVS auf loadb1.example.com und loadb2.example.com:

loadb1.example.com / loadb2.example.com:

modprobe ip_vs_dh
modprobe ip_vs_ftp
modprobe ip_vs
modprobe ip_vs_lblc
modprobe ip_vs_lblcr
modprobe ip_vs_lc
modprobe ip_vs_nq
modprobe ip_vs_rr
modprobe ip_vs_sed
modprobe ip_vs_sh
modprobe ip_vs_wlc
modprobe ip_vs_wrr

Um die IPVS Kernel Module beim Hochfahren zu laden, listen wir die Module in /etc/modules auf:

loadb1.example.com / loadb2.example.com:

vi /etc/modules

ip_vs_dh
ip_vs_ftp
ip_vs
ip_vs_lblc
ip_vs_lblcr
ip_vs_lc
ip_vs_nq
ip_vs_rr
ip_vs_sed
ip_vs_sh
ip_vs_wlc
ip_vs_wrr

Nun bearbeiten wir /etc/apt/sources.list und fügen die Ultra Monkey Paketdatenbanken (entferne nicht die anderen Paketdatenbanken) hinzu. Dann installieren wir Ultra Monkey:

loadb1.example.com / loadb2.example.com:

vi /etc/apt/sources.list

deb http://www.ultramonkey.org/download/3/ sarge main
deb-src http://www.ultramonkey.org/download/3 sarge main

apt-get update
apt-get install ultramonkey libdbi-perl libdbd-mysql-perl libmysqlclient14-dev

Nun wird Ultra Monkey installiert. Wenn Du diese Warnung siehst:

  ¦ libsensors3 not functional                                               ¦
  ¦                                                                          ¦
  ¦ It appears that your kernel is not compiled with sensors support. As a   ¦
  ¦ result, libsensors3 will not be functional on your system.               ¦
  ¦                                                                          ¦
  ¦ If you want to enable it, have a look at "I2C Hardware Sensors Chip      ¦
  ¦ support" in your kernel configuration.                                   ¦

kannst Du sie ignorieren.

Beantworte folgende Fragen:

Do you want to automatically load IPVS rules on boot?
<– No

Select a daemon method.
<– none

Das libdbd-mysql-perl Paket, das wir soeben installiert haben, funktioniert nicht mit MySQL 5 (wir verwenden MySQL 5 auf unserem MySQL Cluster…), also installieren wir das neuste DBD::mysql Perl Paket:

loadb1.example.com / loadb2.example.com:

cd /tmp
wget http://search.cpan.org/CPAN/authors/id/C/CA/CAPTTOFU/DBD-mysql-3.0002.tar.gz
tar xvfz DBD-mysql-3.0002.tar.gz
cd DBD-mysql-3.0002
perl Makefile.PL
make
make install

Wir müssen die Paketweiterleitung aktivieren:

loadb1.example.com / loadb2.example.com:

vi /etc/sysctl.conf

# Enables packet forwarding
net.ipv4.ip_forward = 1

sysctl -p

6.2 Konfiguration von heartbeat

Als Nächstes konfigurieren wir heartbeat indem wir drei Dateien erstellen (alle drei Dateien müssen auf loadb1.example.com und loadb2.example.com identisch sein):

loadb1.example.com / loadb2.example.com:

vi /etc/ha.d/ha.cf

logfacility        local0
bcast        eth0
mcast eth0 225.0.0.1 694 1 0
auto_failback off
node        loadb1
node        loadb2
respawn hacluster /usr/lib/heartbeat/ipfail
apiauth ipfail gid=haclient uid=hacluster

Bitte beachte: Du musst die Systemnamen auflisten (in diesem Fall loadb1 und loadb2) wie von Folgendem gezeigt wird

uname -n

Neben dem genannten musst Du in der Datei nichts ändern.

vi /etc/ha.d/haresources

loadb1
        ldirectord::ldirectord.cf
        LVSSyncDaemonSwap::master
        IPaddr2::192.168.0.105/24/eth0/192.168.0.255

Du musst einen der Load Balancer Systemnamen auflisten (hier: loadb1) sowie die virtuelle IP Adresse (192.168.0.105) zusammen mit der korrekten Netzmaske (24) und Broadcast Adresse (192.168.0.255). Wenn Du Dir mit den Einstellungen nicht ganz sicher bist, kann Dir http://www.subnetmask.info/ vielleicht helfen.

vi /etc/ha.d/authkeys

auth 3
3 md5 somerandomstring

somerandomstring ist ein Passwort, das die beiden heartbeat Daemons auf loadb1 und loadb2 verwenden, um sich gegeneinander zu authentifizieren. Verwende hier Deine eigene Zeichenfolge. Du hast die Wahl zwischen drei Authentifizierungsmechanismen. Ich verwende md5, da dies die sicherste Variante ist.

/etc/ha.d/authkeys sollte nur vom Root-Benutzer gelesen werden können, daher führen wir dies aus:

loadb1.example.com / loadb2.example.com:

chmod 600 /etc/ha.d/authkeys

6.3 Konfiguration von ldirectord

Nun erstellen wir die Konfigurationsdatei für ldirectord, den Load Balancer:

loadb1.example.com / loadb2.example.com:

vi /etc/ha.d/ldirectord.cf

# Global Directives
checktimeout=10
checkinterval=2
autoreload=no
logfile="local0"
quiescent=yes

virtual = 192.168.0.105:3306
        service = mysql
        real = 192.168.0.101:3306 gate
        real = 192.168.0.102:3306 gate
        checktype = negotiate
        login = "ldirector"
        passwd = "ldirectorpassword"
        database = "ldirectordb"
        request = "SELECT * FROM connectioncheck"
        scheduler = wrr

Bitte gib die korrekte virtuelle IP Adresse (192.168.0.105) und die korrekten IP adressen Deiner MySQL Cluster Systeme (192.168.0.101 und 192.168.0.102) ein. 3306 ist der Port, auf dem MySQL standardmäßig läuft. Wir legen außerdem einen MySQL Benutzer (ldirector) und Passwort (ldirectorpassword) fest, eine Datenbank (ldirectordb) und eine SQL Anfrage. ldirectord verwendet diese Information um Test-Anfragen an die MySQL Cluster Systeme zu senden, um zu überprüfen, ob sie immer noch verfügbar sind. Wir werden im nächsten Schritt die ldirector Datenbank mit dem ldirector Benutzer erstellen.

Nun erstellen wir die notwendigen System Startup Links für heartbeat und entfernen die von ldirectord (da ldirectord von heartbeat gestartet wird):

loadb1.example.com / loadb2.example.com:

update-rc.d -f heartbeat remove
update-rc.d heartbeat start 75 2 3 4 5 . stop 05 0 1 6 .
update-rc.d -f ldirectord remove

6.4 Eine Datenbank mit der Bezeichnung ldirector erstellen

Als Nächstes erstellen wir die ldirector Datenbank auf unseren MySQL Cluster Systemen sql1.example.com und sql2.example.com. Diese Datenbank wird von unseren Load Balancern verwendet, um die Verfügbarkeit der MySQL Cluster Systeme zu überprüfen.

sql1.example.com:

mysql -u root -p
GRANT ALL ON ldirectordb.* TO ‚ldirector’@’%‘ IDENTIFIED BY ‚ldirectorpassword‘;
FLUSH PRIVILEGES;
CREATE DATABASE ldirectordb;
USE ldirectordb;
CREATE TABLE connectioncheck (i INT) ENGINE=NDBCLUSTER;
INSERT INTO connectioncheck () VALUES (1);
quit;

sql2.example.com:

mysql -u root -p
GRANT ALL ON ldirectordb.* TO ‚ldirector’@’%‘ IDENTIFIED BY ‚ldirectorpassword‘;
FLUSH PRIVILEGES;
CREATE DATABASE ldirectordb;
quit;

6.5 Die MySQL Cluster Systeme für das Load Balancing vorbereiten

Schließlich müssen wir unsere MySQL Cluster Systeme sql1.example.com und sql2.example.com konfigurieren, damit sie Anfragen auf der virtuellen IP Adresse 192.168.0.105 akzeptieren.

sql1.example.com / sql2.example.com:

apt-get install iproute

Füge Folgendes /etc/sysctl.conf hinzu:

sql1.example.com / sql2.example.com:

vi /etc/sysctl.conf

# Enable configuration of arp_ignore option
net.ipv4.conf.all.arp_ignore = 1

# When an arp request is received on eth0, only respond if that address is
# configured on eth0. In particular, do not respond if the address is
# configured on lo
net.ipv4.conf.eth0.arp_ignore = 1

# Ditto for eth1, add for all ARPing interfaces
#net.ipv4.conf.eth1.arp_ignore = 1

# Enable configuration of arp_announce option
net.ipv4.conf.all.arp_announce = 2

# When making an ARP request sent through eth0 Always use an address that
# is configured on eth0 as the source address of the ARP request.  If this
# is not set, and packets are being sent out eth0 for an address that is on
# lo, and an arp request is required, then the address on lo will be used.
# As the source IP address of arp requests is entered into the ARP cache on
# the destination, it has the effect of announcing this address.  This is
# not desirable in this case as adresses on lo on the real-servers should
# be announced only by the linux-director.
net.ipv4.conf.eth0.arp_announce = 2

# Ditto for eth1, add for all ARPing interfaces
#net.ipv4.conf.eth1.arp_announce = 2

sysctl -p

Füge diesen Bereich für die virtuelle IP Adresse /etc/network/interfaces hinzu:

sql1.example.com / sql2.example.com:

vi /etc/network/interfaces

auto lo:0
iface lo:0 inet static
  address 192.168.0.105
  netmask 255.255.255.255
  pre-up sysctl -p > /dev/null

ifup lo:0

7 Starte den Load Balancer und führe Tests durch

Nun können wir unsere beiden Load Balancer zum ersten Mal starten:

loadb1.example.com / loadb2.example.com:

/etc/init.d/ldirectord stop
/etc/init.d/heartbeat start

Wenn Du keine Fehlermeldungen siehst, solltest Du nun beide Load Balancer neu starten:

loadb1.example.com / loadb2.example.com:

shutdown -r now

Nach dem Neustart können wir überprüfen, ob beide Load Balancer wie erwartet funktionieren:

loadb1.example.com / loadb2.example.com:

ip addr sh eth0

Der aktiver Load Balancer sollte die virtuelle IP Adresse (192.168.0.105) auflisten:

2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:16:3e:45:fc:f8 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.103/24 brd 192.168.0.255 scope global eth0
    inet 192.168.0.105/24 brd 192.168.0.255 scope global secondary eth0

Der hot-standby sollte dies zeigen:

2: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:16:3e:16:c1:4e brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.104/24 brd 192.168.0.255 scope global eth0

loadb1.example.com / loadb2.example.com:

ldirectord ldirectord.cf status

Ausgabe auf dem aktiven Load Balancer:

ldirectord for /etc/ha.d/ldirectord.cf is running with pid: 1603

Ausgabe auf dem hot-standby:

ldirectord is stopped for /etc/ha.d/ldirectord.cf

loadb1.example.com / loadb2.example.com:

ipvsadm -L -n

Ausgabe auf dem aktiven Load Balancer:

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.105:3306 wrr
  -> 192.168.0.101:3306           Route   1      0          0
  -> 192.168.0.102:3306           Route   1      0          0

Ausgabe auf dem hot-standby:

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

loadb1.example.com / loadb2.example.com:

/etc/ha.d/resource.d/LVSSyncDaemonSwap master status

Ausgabe auf dem aktiven Load Balancer:

master running
(ipvs_syncmaster pid: 1766)

Ausgabe auf dem hot-standby:

master stopped
(ipvs_syncbackup pid: 1440)

Wenn Deine Tests geklappt haben, kannst Du nun versuchen auf die MySQL Datenbank von einem völlig anderen Server im gleichen Netzwerk aus zuzugreifen (192.168.0.x) indem Du die virtuelle IP Adresse 192.168.0.105 verwendest:

mysql -h 192.168.0.105 -u ldirector -p

(Bitte beachte: Dein MySQL Client muss mindestens Version 4.1 sein; ältere Versionen funktionieren mit MySQL 5 nicht.)

Du kannst nun eines der MySQL Cluster Systeme zu Testzwecken ausschalten; Du müsstest dann immer noch in der Lage sein, Dich mit der MySQL Datenbank in Verbindung zu setzen.

8 Anmerkungen

Es gibt einige Dinge, an die man denken muss, wenn man ein MySQL Cluster ausführt:

Alle Daten werden im RAM gespeichert! Daher benötigst Du eine Menge RAM auf Deinen Cluster Systemen. Die Formel, wieviel RAM Du für jedes System benötigst, lautet:

(SizeofDatabase × NumberOfReplicas × 1.1 ) / NumberOfDataNodes

Wenn Du also eine Datenbank hast, die eine Größe von 1 GB aufweist, bräuchtest Du 1.1 GB RAM auf jedem einzelnen System!

– Das Cluster Management System hört auf Port 1186 und jeder kann sich verbinden. Das ist definitiv nicht sicher, daher  solltest Du Dein Cluster in einem isolierten privaten Netzwerk ausführen!

Sieh Dir am Besten mal die MySQL Cluster FAQs an: http://dev.mysql.com/doc/refman/5.0/en/mysql-cluster-faq.html sowie die MySQL Cluster Dokumentation: http://dev.mysql.com/doc/refman/5.0/en/ndbcluster.html

Links

MySQL: http://www.mysql.com/

MySQL Cluster documentation: http://dev.mysql.com/doc/refman/5.0/en/ndbcluster.html

MySQL Cluster FAQ: http://dev.mysql.com/doc/refman/5.0/en/mysql-cluster-faq.html

Ultra Monkey: http://www.ultramonkey.org/

The High-Availability Linux Project: http://www.linux-ha.org/

Das könnte dich auch interessieren …