Dit is het vijfde deel van onze Tutorialseries: 'Een redundante VPS-omgeving inrichten'. Ben je een nieuwe redundante VPS-omgeving aan het inrichten, dan raden wij aan om bij deel 1 te beginnen en geen delen over te slaan.
In dit deel laten we zien hoe je een MariaDB master-slave setup met MaxScale gebruikt met een PHP-applicatie/website en voor WordPress-websites. Deze materie behandelen wij in de volgende onderwerpen:
- Opties om je database te koppelen
- Keepalived installeren en configureren
- Je database aan een PHP-applicatie koppelen
- Je database aan een WordPress-website koppelen
Voer alle stappen in dit artikel uit met een gebruiker met root-rechten, tenzij anders vermeld.
Opties om je database te koppelen
Er zijn diverse opties om je database aan je applicatie te koppelen: Je kunt in je applicatie SQL-queries naar het private network IP-adres van je master-VPS sturen en bijvoorbeeld de read-queries naar de slave-VPS, of alle queries naar de master. Dit is echter weinig flexibel wanneer je een handmatige of automatische failover gebruikt.
Een andere en allicht 'eenvoudigere' manier om met meer flexibiliteit je SQL-database aan je website of applicatie te koppelen, ongeacht of je automatische of handmatige failover gebruikt, is een virtueel IP-adres te gebruiken voor write-queries en read-queries. Dit virtuele IP-adres geef je aan je VPS via Keepalived.
Een virtueel IP-adres van Keepalived koppelt een fictief/virtueel IP-adres aan één of meerdere bestaande IP-adressen op een of meerdere servers. Dit virtuele IP-adres gaat bij downtime van de ene VPS automatisch over op de andere. Het is een fictief-adres dat niets anders doet dan reguleren naar welk bestaand (niet-fictief) IP-adres verkeer gaat.
Het grote voordeel van het gebruik van een virtueel IP-adres is dat in je website of applicatie, je voor write- en/of read-queries simpelweg dit virtuele IP-adres instelt. Zo maakt het niet uit welke VPS er bijvoorbeeld de master is. Zolang de master het virtuele IP-adres maar heeft, komen write-queries op de juiste server uit. Wij raden aan een van de volgende drie configuraties te hanteren:
- Één virtueel IP-adres voor zowel write- als read-queries: Alle SQL-queries gaan naar de master-VPS. Bij failover wordt de slave-VPS de nieuwe master-VPS en krijgt die het virtuele IP-adres. De slave-VPS zal dan bij een failover dus alle SQL-queries te verwerken.
- Één virtueel IP-adres voor write-queries en één virtueel IP-adres voor read-queries: Voor een lichte vorm van loadbalancing kun je twee virtuele IP-adressen instellen: één adres voor write-queries naar de master, en één adres voor read-queries naar de slave.
-
Één virtueel IP-adres voor write-queries en HA-Proxy voor read-queries: Een elegante oplossing zou zijn om één virtueel IP-adres write-queries naar je master VPS te laten sturen en HA-Proxy inzetten voor read-queries om zo read-queries over al je gekoppelde database servers te verdelen. HA-Proxy valt echter buiten de scope van deze tutorials.
HA-IP en HA-IP Pro kunnen op moment van schrijven nog niet gebruikt worden op private networks. Indien/wanneer dit wel geïmplementeerd wordt passen wij daarop deze handleiding aan en zal die methode de voorkeur hebben.
De eerste twee voorbeelden hierboven worden in dit artikel nader toegelicht.
Houd er rekening mee bij een failover dat je controleert of het virtuele IP-adres is overgegaan op de slave of niet (dit hangt o.a. af van de oorzaak van de failover). Zo niet, dan zet je handmatig Keepalived uit op de master met het commando:
systemctl stop keepalived
Keepalived installeren en configureren
Wij gebruiken voor de write-acties een virtueel IP-adres via Keepalived. Dit virtuele IP-adres is een nep IP-adres dat gekoppeld is aan een bestaand IP-adres. Je hebt controle over aan welke server dit virtuele IP-adres gekoppeld is en het kan ook automatisch overgaan op een andere VPS, wanneer een VPS onbereikbaar wordt.
Voer onderstaande stappen uit op alle VPS'en in je cluster als root-user.
Stap 1
Installeer Keepalived met onderstaand commando.
CentOS / AlmaLinux / Rocky Linux:
yum -y install keepalived
of voor nieuwere installaties:
dnf -y install keepalived
Debian / Ubuntu:
apt -y install keepalived
Stap 2
Schakel Keepalived in en zorgt dat het ook bij een herstart van je VPS automatisch weer opkomt.
systemctl enable keepalived
Stap 3
Open het Keepalived-configuratiebestand met je favoriete editor, bijvoorbeeld:
nano /etc/keepalived/keepalived.conf
In Ubuntu bestaat dit bestand nog niet. Je krijgt op Ubuntu dus een leeg bestand te zien.
Stap 4
Zorg dat de inhoud van het bestand er uit ziet zoals in onderstaande voorbeelden. Voor de duidelijkheid zijn hier de inhoud van zowel de master als de slave opgenomen voor de twee eerder genoemde scenario's:
- Één virtueel IP-adres voor zowel write- als read-queries
- Één virtueel IP-adres voor write-queries en één virtueel IP-adres voor read-queries
Onder de voorbeelden volgt een toelichting en wordt aangegeven welke gegevens je moet aanpassen naar die van je eigen VPS.
Let op: bij CentOS staat er nog aanzienlijk meer code in dit configuratiebestand. Verwijder in dat geval de gehele inhoud en vervang het door het bovenstaande.
- state MASTER / BACKUP: Geef in de configuratie van je master-VPS state MASTER op en op de slave-VPS('en) state BACKUP.
- interface eth1: Geef hier de naam van je netwerkinterface op. Je controleert je netwerkinterface naam met het commando ip a. In dit geval gebruiken wij de interface van het private network
- virtual_router_id: Geef per IP-adres (niet per VPS) een uniek nummer op.
- priority: Het hoogste getal krijgt prioriteit over het laagste. Geef dus bij de master-VPS hier een hoger getal op dan op de slave(s).
- unicast_src_ip: Geef het IP-adres op van de VPS waarop je deze stappen doorloopt. Wij gebruiken hier het IP-adres van het private network.
- unicast_peer: Geef de IP-adressen op van de andere VPS'en in je database cluster, waarbij je ieder IP-adres op een aparte regel plaatst.
- virtual_ipaddress: Vul het virtuele IP-adres in dat je wil gebruiken. Het maakt in principe niet uit welk virtueel IP-adres je gebruikt, zo lang je maar op de master en slave(s) hetzelfde virtuele IP-adres opgeeft en die op hetzelfde subnet zit als de IP-adressen van je private network.
Stap 5
Herstart vervolgens keepalived om de wijzigingen te verwerken.
systemctl restart keepalived
Wanneer je nu je IP-adressen bekijkt met ip a zie je op je master het virtuele IP-adres terug. Op je slave-VPS('en) zal deze niet terug te zien zijn.
Tip: Test direct je virtuele IP door op je master hem even uit te zetten (systemctl stop keepalived) en op je slave je IP-adressen te bekijken (ip a). Vergeet niet na je test weer keepalived aan te zetten (systemctl start keepalived).
Tot slot
In je applicatie configureer je nu afhankelijk van de keuzes die je eerder hebt gemaakt, dat alle SQL-queries op je primaire Keepalived IP-adres worden uitgevoerd dat aan je master-VPS is gekoppeld. Read-queries worden eventueel op het secondaire IP-adres dat op dit moment aan je slave-VPS is gekoppeld uitgevoerd, of op je master-VPS.
Hoe dit werkt met twee virtuele IP's laten wij hieronder zien voor PHP en WordPress. Deze principes werken ook hetzelfde in andere type applicaties (e.g. Java).
Je database aan je PHP-applicatie koppelen
Gebruik je één virtueel IP-adres voor write-en read-queries, dan zijn er geen bijzondere aanpassingen nodig. Het enige dat je dan verandert in je PHP-configuratie is dat je het virtuele IP-adres gebruikt om SQL-queries naartoe te schrijven, bijvoorbeeld:
<?php
/* Database settings */
$server = "192.168.1.100";
$username = "gebruiker";
$password = "wachtwoord";
$link_to_server = mysqli_connect(
$server,
$username,
$password,
'wordpress');
if (!$link_to_server) {
printf("Unable to connect to write server. Error: %s", mysqli_connect_error());
exit;
}
mysqli_close($link_to_server);
?>
Gebruik je twee virtuele IP's, of één virtueel IP en HA-Proxy (of een specifiek adres voor read-queries), dan definieer je in PHP apart een write- en read-server. Hieronder volgt een voorbeeld hoe je vervolgens de write- en read-queries van elkaar scheidt in PHP, met onder de code een korte toelichting van de configuratie.
<?php /* Write settings */ $write_server = "192.168.1.100"; $write_username = "gebruiker"; $write_password = "wachtwoord"; /* read settings */ $read_server = "192.168.1.101"; $read_username = "gebruiker"; $read_password = "wachtwoord"; $link_to_writer = mysqli_connect( $write_server, $write_username, $write_password, 'wordpress'); if (!$link_to_writer) { printf("Unable to connect to write server. Error: %s", mysqli_connect_error()); exit; } $link_to_reader = mysqli_connect( $read_server, $read_username, $read_password, 'wordpress'); if (!$link_to_reader) { printf("Unable to connect read server. Error: %s", mysqli_connect_error()); exit; } mysqli_close($link_to_writer); mysqli_close($link_to_reader); ?>
Je database aan een WordPress-site koppelen
Gebruik je één enkel virtueel IP-adres, dan is je configuratie gelukkig zeer eenvoudig. Je past in wp-config.php enkel je database aan naar het virtuele IP-adres:
// ** MySQL settings ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'WordPress' );
/** MySQL database username */
define( 'DB_USER', 'example' );
/** MySQL database password */
define( 'DB_PASSWORD', 'your_password' );
/** MySQL hostname */
define( 'DB_HOST', '192.168.1.100' );
Gebruik je één virtueel IP-adres voor write-queries en een ander IP-adres voor read-queries, dan komt er meer bij kijken en gebruik je de onderstaande stappen.
WordPress is wereldwijd het meest gebruikte CMS-systeem. Een gedegen ondersteuning voor databaseclusters is dan ook meer dan wenselijk. Gelukkig is deze ondersteuning er in de vorm van een geavanceerde plugin: HyperDB. Met deze plugin maakt je WordPress website gebruik van het database-cluster die je in de vorige twee delen hebt geconfigureerd.
Onderstaande stappen voer je uit op alle VPS'en in je master/slave-setup.
Stap 1
Voeg eerst de HyperDB-plugin toe aan je WordPress. Dit werkt iets anders bij HyperDB dan bij reguliere plugins: De bestanden die HyperDB gebruikt worden namelijk niet in de standaard plugin-directory geplaatst. Haal dus eerst HyperDB rechtstreeks binnen op je VPS (de meest actuele versie vind je hier):
wget
https://downloads.wordpress.org/plugin/hyperdb.1.8.zip
Stap 2
Pak vervolgens hyperdb.1.5.zip uit en verwijder daarna het .zip-bestand:
unzip hyperdb.1.8.zip
rm -f hyperdb.1.8.zip
Stap 3
HyperDB komt met 2 bestanden: db-config.php en db.php. Plaats db-config.php in dezelfde map als waar wp-config.php in staat en db.php in de /wp-content/ map. Plaats je de bestanden ergens anders dan werkt je WordPress-site niet meer.
mv /home/transip/hyperdb/db-config.php /var/www/voorbeeld.nl/
mv /home/transip/hyperdb/db.php /var/www/voorbeeld.nl/wp-content/
Let wel dat je de directory hierboven aanpast naar de daadwerkelijke directory waar je WordPress-website in staat.
Stap 4
Open het bestand db-config.php met je favoriete editor, bijvoorbeeld:
nano /var/www/voorbeeld.nl/db-config.php
Stap 5
Zoek in dit bestand naar het onderstaande stuk code.
/** Sample Configuration 1: Using the Default Server **/
/** NOTE: THIS IS ACTIVE BY DEFAULT. COMMENT IT OUT. **/
Sample 1 gaan we gebruiken, maar sample 2 niet. Commentaar sample 2 uit zoals in het voorbeeld hieronder, of verwijder dit stuk in zijn geheel.
/** Sample Configuration 2: Partitioning **/
/**
* This example shows a setup where the multisite blog tables have been
* separated from the global dataset.
*
*
*$wpdb->add_database(array(
* 'host' => 'global.db.example.com',
* 'user' => 'globaluser',
* 'password' => 'globalpassword',
* 'name' => 'globaldb',
*));
*$wpdb->add_database(array(
* 'host' => 'blog.db.example.com',
* 'user' => 'bloguser',
* 'password' => 'blogpassword',
* 'name' => 'blogdb',
* 'dataset' => 'blog',
*));
*$wpdb->add_callback('my_db_callback');
*function my_db_callback($query, $wpdb) {
* // Multisite blog tables are "{$base_prefix}{$blog_id}_*"
* if ( preg_match("/^{$wpdb->base_prefix}\d+_/i", $wpdb->table) )
* return 'blog';
*}
*/
Stap 6
Scroll nu terug naar Sample Configuration 1 en pas de code aan zoals in onderstaand voorbeeld.
$wpdb->add_database(array(
'host' => DB_HOST, // If port is other than 3306, use host:port.
'user' => DB_USER,
'password' => DB_PASSWORD,
'name' => DB_NAME,
'write' => 1,
'read' => 0,
));
/**
* This adds the same server again, only this time it is configured as a slave.
* The last three parameters are set to the defaults but are shown for clarity.
*/
$wpdb->add_database(array(
'host' => DB_SLAVE, // If port is other than 3306, use host:port.
'user' => DB_USER,
'password' => DB_PASSWORD,
'name' => DB_NAME,
'write' => 0,
'read' => 1,
'dataset' => 'global',
'timeout' => 0.2,
));
- Het eerste deel is de configuratie van de master. Hierin zijn de write- en read-regel toegevoegd. Hiermee stel je in dat de master enkel write acties uitvoert (op read acties komen we in stap 8 terug).
- In het tweede deel pas je de naam DB_HOST aan naar DB_SLAVE. De instellingen laat je verder staan zoals ze zijn. Wij komen zo terug op hoe je zorgt dat de master en slave van rol kunnen wisselen bij een failover.
- Wil je een derde of vierde slave toevoegen, dan herhaal je het onderste deel maar pas je de naam aan naar DB_SLAVE1, DB_SLAVE2, etc.
Sla de wijzigingen tot slot op en sluit het bestand (ctrl + x > y).
Stap 7
Open vervolgens je WordPress configuratiebestand.
nano /var/www/voorbeeld.nl/wp-config.php
Stap 8
Pas het volgende stukje aan...
/** MySQL hostname */
define ('DB_HOST', 'localhost');
...zodat het er uit ziet als hieronder. Pas de IP's aan naar respectievelijk je Virtuele IP van Keepalived (master) en je private network IP-adres (slave). Gebruik je geen Keepalived, gebruik dan het private network IP-adres van je master onder DB_HOST.
Stel op webserver 1 het private network
/** MySQL master */ define ('DB_HOST', '192.168.1.100'); /** MySQL slave */ define ('DB_SLAVE', '
192.168.1.101');
Voor read-queries stel je de variabele DB_SLAVE in om read-queries naar het private network IP-adres van de SQL-slave te sturen.
Optioneel: Je bent vrij wp-config.php op webserver 1 naar het private network IP-adres van de DB-master read-queries te laten schrijven, en op webserver 2 naar het private network IP-adres van de DB-slave. Let wel dat je in dat geval read=1 voor de master instelt. Dit kan bijvoorbeeld handiger zijn als je de load evenredig wil verdelen en er niet veel write-queries worden uitgevoerd op de WordPress website.
Sla tot slot wederom de wijzigingen op en sluit het bestand (ctrl + x > y).
Wat te doen in geval van een failover-situatie
Stel dat de situatie zich voordoet dat je SQL-master offline gaat. Dankzij MaxScale kan de slave-VPS dan handmatig of automatisch de nieuwe master worden. Het Keepalived IP-adres zal hoe dan ook automatisch overgaan. Wanneer vervolgens de oude master online komt, zal die als slave worden toegevoegd, maar krijgt wel weer het Keepalived IP-adres terug.
Dit zou ertoe leiden dat write-queries niet langer worden geschreven naar de VPS die op dat moment als master werkt. In een dergelijk geval raden wij aan eerst Keepalived uit te zetten op de oude master, zodat die eventuele gemiste data kan synchroniseren. Daarna schakel je Keepalived weer in en voer je een handmatig switchover-commando uit (zie het vorige deel voor dit commando), om de oude master weer te promoten tot master van het cluster.
Alternatief kun je MaxScale configureren op de oorspronkelijke master-VPS om een script te gebruiken bij een new_slave event (i.e. de oude master wordt als nieuwe slave toegevoegd). Je laat bijvoorbeeld het script dan Keepalived uitzetten op de oorspronkelijke master (zie deze pagina onder Script events en ons artikel over split-brain, voor meer informatie over het werken met MaxScale events en scripts).
Je bent nu klaar met de configuratie van je SQL-cluster! Bekijk het laatste deel (sla die zeker niet over! voor aanvullende tips voor je database setup, zoals beheercommando's en extra MariaDB Monitor opties.