Hulpartikel overzicht

Hulpartikel

Linux redundantie tutorial 5: je database cluster gebruiken

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 combineert gebruikt op je PHP-applicatie/website, of je WordPress-website. In dit deel behandelen we deze materie in de volgende onderwerpen:

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 je VPS via Keepalived.

Een virtueel IP-adres van Keepalived koppelt een fictief/virtueel IP-adres dat is gelinkt aan één of meerdere bestaand 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 eigenlijk niets anders doet dan reguleren naar welk bestaand 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:

yum -y install keepalived

Debian / Ubuntu:

apt-get 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.

Één virtueel IP-adres voor zowel write- als read-queries

Master-configuratie

! Configuration File for keepalived

global_defs {
   vrrp_skip_check_adv_addr
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface eth1
    virtual_router_id 51
    priority 105
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    unicast_src_ip 192.168.1.1
    unicast_peer {
            192.168.1.2
    }
    virtual_ipaddress {
        192.168.1.100
   }
}

Slave-configuratie

! Configuration File for keepalived

global_defs {
   vrrp_skip_check_adv_addr
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth1
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    unicast_src_ip 192.168.1.2
    unicast_peer {
            192.168.1.1
    }
    virtual_ipaddress {
        192.168.1.100
   }
}
Één virtueel IP-adres voor write-queries en één virtueel IP-adres voor read-queries

Stel dat je voor deze optie kiest in je configuratie, dan breid je de configuratie uit zodat je twee virtuele IP's hebt. De master-VPS heeft de prioriteit voor het ene IP-adres, de slave voor het andere. De configuratie hiervan zou er bijvoorbeeld als volgt uitzien:

master-configuratie

! Configuration File for keepalived

global_defs {
   vrrp_skip_check_adv_addr
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state MASTER
    interface eth1
    virtual_router_id 51
    priority 105
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    unicast_src_ip 192.168.1.1
    unicast_peer {
            192.168.1.2
    }
    virtual_ipaddress {
        192.168.1.100
   }
}

vrrp_instance VI_2 {
    state BACKUP
    interface eth1
    virtual_router_id 52
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    unicast_src_ip 192.168.1.1
    unicast_peer {
            192.168.1.2
    }
    virtual_ipaddress {
        192.168.1.101
   }
}

slave-configuratie

! Configuration File for keepalived

global_defs {
   vrrp_skip_check_adv_addr
   vrrp_garp_interval 0
   vrrp_gna_interval 0
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth1
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    unicast_src_ip 192.168.1.2
    unicast_peer {
            192.168.1.1
    }
    virtual_ipaddress {
        192.168.1.100
   }
}

vrrp_instance VI_1 {
    state MASTER
    interface eth1
    virtual_router_id 52
    priority 105
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    unicast_src_ip 192.168.1.2
    unicast_peer {
            192.168.1.1
    }
    virtual_ipaddress {
        192.168.1.101
   }
}

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.

ip a output with keepalived virtual IP

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);
?>
Toelichting op code
  • Gebruik voor het IP-adres in de variabele $write_server het Keepalived IP-adres als je een automatische failover setup met Keepalived gebruikt, of het private network IP-adres van je Master-VPS als je geen Keepalived gebruikt.
     
  • Voor read-queries stel je de variabele $read_server op webserver 1 in om read-queries naar de SQL-master te sturen en op webserver 2 naar de SQL-slave. Voert je master intensief veel write-queries uit, dan wil je misschien liever alle read-queries naar je slave sturen.
    Optioneel: Gebruik je geen automatische failover, stuur dan alle read- en write-queries naar het virtuele Keepalived IP-adres.
     
  • De $write_username en $read_username zijn je SQL-gebruikers en zijn bij beide velden dezelfde, evenals de respectievelijke bijbehorende wachtwoorden.
     
  • De reader laat je in je PHP-code alle read-queries (SELECT .... FROM ....) uitvoeren. Alle overige queries worden door de writer gedaan.
     
  • De ins- en outs van PHP-code vallen verder buiten de scope van deze tutorial series.

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.5.zip

 

Stap 2

Pak vervolgens hyperdb.1.5.zip uit en verwijder daarna het .zip-bestand:

unzip hyperdb.1.5.zip
rm -f hyperdb.1.5.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 je private network IP-adres (gebruik je geen Keepalived, gebruik dan het private network IP-adres van je master).

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. MaxScale zorgt er dan voor dat je slave handmatig of automatisch de nieuwe master wordt. 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), 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 voor enkele aanvullende tips voor je database setup, zoals beheercommando's, extra MariaDB Monitor opties.

Mocht je aan de hand van dit artikel nog vragen hebben, aarzel dan niet om onze supportafdeling te benaderen. Je kunt hen bereiken via de knop 'Neem contact op' onderaan deze pagina.

Wil je dit artikel met andere gebruikers bespreken, laat dan vooral een bericht achter onder 'Reacties'.

Heb je ook een goed idee?

Stuur jouw idee in! Met genoeg stemmen komt jouw idee op onze wishlist!

Heeft dit artikel je geholpen?

Maak een account aan of log in om een beoordeling achter te laten.

Reacties

Maak een account aan of log in om een reactie te plaatsen.

Kom je er niet uit?

Ontvang persoonlijke hulp van onze supporters

Neem contact op