L'importance de la haute disponibilité (HA) est devenue cruciale aujourd'hui, notamment avec la dépendance croissante des entreprises aux applications en ligne, aux services numériques et aux plateformes de données. La HA permet d'assurer que ces services restent accessibles et fonctionnels, même en cas de défaillances matérielles, logicielles ou réseau. Pour les entreprises, une perte d'accès, même de courte durée, peut entraîner des conséquences significatives : perte de revenus, perte de confiance des clients et des partenaires, voire des risques légaux dans certains secteurs.
Les bases de données sont au cœur des systèmes d'information. Elles stockent et gèrent les données essentielles de nombreuses applications, ce qui les rend critiques pour la continuité des services. La spécificité des SGBD en matière de haute disponibilité réside dans leur nature transactionnelle et leur besoin de cohérence des données. En cas de panne ou d'interruption, il est impératif que les données restent cohérentes et que la continuité des transactions soit garantie.
Dans les environnements critiques, comme le commerce en ligne, la finance, la santé et les télécommunications, des bases de données disponibles 24/7 sont essentielles. De plus, avec l’augmentation du volume de données et des transactions, les entreprises ont besoin de solutions scalables qui maintiennent la performance sans sacrifier la disponibilité ni la cohérence.
Des solutions comme Galera Cluster pour MySQL/MariaDB et des technologies comme la réplication synchrone et les topologies multi-maîtres sont devenues des choix populaires pour répondre à ces besoins. Ces solutions permettent non seulement d'assurer la disponibilité des SGBD, mais aussi d'améliorer la résilience et la performance des systèmes de gestion de bases de données, essentielles dans un contexte où les interruptions ne sont pas acceptables.
Galera Cluster est une solution de réplication synchrone pour les bases de données MySQL et MariaDB. Il est conçu pour assurer une haute disponibilité et une tolérance aux pannes en permettant la répartition de la charge sur plusieurs nœuds. Voici ses principales fonctionnalités et avantages :
Galera Cluster est une solution robuste et adaptée aux applications critiques qui nécessitent des performances élevées et une haute disponibilité pour leurs bases de données.
Dans un cluster qui utilise un quorum pour la haute disponibilité, il est recommandé d'avoir un nombre impair de nœuds. Le quorum est un mécanisme utilisé pour déterminer la majorité des nœuds actifs dans un cluster. Dans un cluster Galera, par exemple, un quorum auto basculant permet de décider si le cluster doit rester opérationnel ou basculer en mode dégradé en cas de défaillance de certains nœuds.
Avoir un nombre impair de nœuds permet d’éviter les égalités lors du calcul du quorum, simplifiant ainsi la prise de décision pour maintenir la cohérence et l'intégrité des données dans le cluster. Si le nombre de nœuds est impair, le cluster peut obtenir une majorité plus facilement, ce qui évite les conflits. Dans un cluster avec un nombre pair de nœuds, il peut y avoir des situations de "split-brain", où deux partitions peuvent prétendre avoir la majorité, ce qui complique la gestion.
Si vous avez un nombre pair de nœuds pour des raisons pratiques ou de charge de travail, une solution consiste à ajouter un nœud arbitre. Ce nœud arbitre participe au vote pour le quorum mais n’héberge pas de données. Cela permet d'obtenir une majorité plus simplement et d’éviter les conflits de quorum. Le package galera-arbitrator
peut jouer ce rôle dans le cadre de Galera Cluster.
le site officiel de Galera Cluster : https://galeracluster.com/
debianSQL1
, adresse IP 192.168.1.11/24
debianSQL2
, adresse IP 192.168.1.12/24
debianSQL3
, adresse IP 192.168.1.13/24
Nous utiliserons debianGUI pour centraliser l'administration des serveurs (en SSH) et naviguer sur le WEB.
Le schéma avec les trois noeuds du cluster :
Nous allons d'abord configurer un premier serveur de référence, sur lequel nous allons également installer une base de données et un utilisateur associé.
Sur le serveur debianSQL1
, installer le service MariaDB :
sudo apt update && sudo apt upgrade && sudo apt -y install mariadb-server
Normalement le package
galera-4
est automatiquement installé avecmariadb-server
, mais on ne risque rien à insister, avec la commande :sudo apt install galera-4
Procéder à l'habituelle configuration de base :
sudo mysql_secure_installation
Dans notre contexte, les réponses à donner sont dans l'ordre : Entrée, n, n, y, y, y, y.
On édite le fichier de configuration de mariadb :
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
Commenter la ligne bind-address
pour autoriser des connexions en dehors de la machine hôte :
# bind-address = 127.0.0.1
Relancer le service
sudo systemctl restart mariadb
Le moteur de stockage des bases de données doit être innoDB ou XtraDB, MyISAM n'est pas pris en charge par Galera. InnoDB est en principe le moteur installé par défaut ; nous pouvons quand même vérifier :
La requête SQL ci-dessous va afficher quel est le moteur de stockage utilisé par défaut sur cette instance :
sudo mysql -u root -e "SHOW VARIABLES LIKE 'default_storage_engine';"
On obtient l'information en retour :
+------------------------+--------+
| Variable_name | Value |
+------------------------+--------+
| default_storage_engine | InnoDB |
+------------------------+--------+
1 row in set (0,001 sec)
sudo mysql -u root
On arrive sur le shell mysql où nous allons créer la base de données pascaldb
ainsi que l'utilisateur pascal
(avec son mot de passe P@55word
) qui aura (quasiment) tous les droits sur la base de données, depuis n'importe quel emplacement :
CREATE DATABASE pascaldb;
GRANT ALL ON pascaldb.* TO 'pascal'@'%' IDENTIFIED BY 'P@55word';
FLUSH PRIVILEGES;
exit;
Nous allons maintenant, à partir de ce serveur initial, déployer le cluster sur les trois noeuds.
Sur les deux autres serveurs, installez MariaDB :
sudo apt update && sudo apt upgrade && sudo apt -y install mariadb-server
Procéder également à l'habituelle configuration de base :
sudo mysql_secure_installation
Sur le serveur primaire, on fait une copie du fichier de configuration par défaut:
sudo cp /etc/mysql/mariadb.conf.d/60-galera.cnf /etc/mysql/mariadb.conf.d/60-galera.cnf.old
Puis on le modifie :
sudo nano /etc/mysql/mariadb.conf.d/60-galera.cnf
Remplacer le contenu par la configuration suivante :
[galera]
# Mandatory settings
wsrep_on = ON
wsrep_provider = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name = "Galera_Cluster_PM"
wsrep_cluster_address = gcomm://192.168.1.11,192.168.1.12,192.168.1.13
binlog_format = row
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
innodb_force_primary_key = 1
# Allow server to accept connections on all interfaces.
bind-address = 0.0.0.0
# Optional settings
#wsrep_slave_threads = 1
#innodb_flush_log_at_trx_commit = 0
log_error = /var/log/mysql/error-galera.log
Quelques explications :
wsrep_on = ON
: activer la réplication en écriture via le provider wsrepwsrep_provider
: emplacement de la librairie wsrepwsrep_cluster_name
: le nom du cluster, doit être identique sur tous les nœuds de votre cluster Galerawsrep_cluster_address
: adresses IP des différents nœuds du cluster (séparées par une virgule)binlog_format
: format des logs en ROW, par défautdefault_storage_engine
: moteur de stockage par défaut, ici InnoDBinnodb_autoinc_lock_mode
: mode pour l'auto-incrémentation, 2 est recommandéinnodb_force_primary_key
: s'assure que toutes les tables ont bien une clé primaire pour éviter les erreursbind-address = 0.0.0.0
: accepter les connexions sur toutes les interfaceslog_error
: emplacement du fichier de log des erreurs (qui contient aussi des logs d'informations, en fait)On va démarrer le cluster avec cet unique noeud primaire. Sur le serveur 1, arrêter MariaDB :
sudo systemctl stop mariadb
et initialiser le cluster :
sudo galera_new_cluster
Ensuite, on va se connecter au shell MariaDB
sudo mysql -u root
pour regarder combien de nœuds constituent notre cluster :
show status like 'wsrep_cluster_size';
Normalement, un seul :
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| wsrep_cluster_size | 1 |
+--------------------+-------+
1 row in set (0,001 sec)
Toujours sous le shell SQL, la commande ci-dessous permet d'obtenir les informations sur l'état du cluster :
show global status like 'wsrep%';
Ce qui peut donner pour nous (je n'affiche qu'une partie de la sortie) :
+-------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+-------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
| wsrep_local_state_uuid | eb71b051-a048-11ef-8fe7-8f72caf18dad |
| wsrep_protocol_version | 11 |
| wsrep_last_committed | 1 |
| wsrep_replicated | 0 |
...
| wsrep_local_state_comment | Synced |
...
| wsrep_incoming_addresses | 192.168.1.11:0 |
| wsrep_cluster_weight | 1 |
...
| wsrep_evs_state | OPERATIONAL |
...
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |
...
+-------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------+
69 rows in set (0,002 sec)
Sur chacun des deux autres serveurs du cluster, on configure à l'identique :
sudo cp /etc/mysql/mariadb.conf.d/60-galera.cnf /etc/mysql/mariadb.conf.d/60-galera.cnf.old
sudo nano /etc/mysql/mariadb.conf.d/60-galera.cnf
[galera]
# Mandatory settings
wsrep_on = ON
wsrep_provider = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name = "Galera_Cluster_PM"
wsrep_cluster_address = gcomm://192.168.1.11,192.168.1.12,192.168.1.13
binlog_format = row
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
innodb_force_primary_key = 1
# Allow server to accept connections on all interfaces.
bind-address = 0.0.0.0
# Optional settings
#wsrep_slave_threads = 1
#innodb_flush_log_at_trx_commit = 0
log_error = /var/log/mysql/error-galera.log
sudo systemctl restart mariadb
Les bases de données existantes des nœuds
debianSQL2
etdebianSQL3
seront supprimées. Il n'y a que les bases de données du premier nœud qui vont exister suite à l'intégration au cluster.
Sur chacun des serveurs, on peut vérifier l'état local du provider. Connectez-vous à MariaDB :
sudo mysql -u root
et vérifiez l'état du cluster, avec la requête suivante :
SHOW STATUS LIKE 'wsrep_%';
Vérifiez que wsrep_cluster_size
est égal à 3 (nombre de noeuds du cluster).
La valeur de wsrep_cluster_status
est Primary
, indiquant que le noeud est bien actif dans le cluster. Si un noeud n'est pas dans cet état, suite à une perte de connexion, il suffit de relancer le service mariadb dessus (sudo systemctl restart mariadb
).
La valeur de wsrep_local_state_comment
doit être synced
.
Enfin, la valeur de wsrep_local_recv_queue_avg
doit être nulle, sinon cela signifie que la synchronisation ne suit pas (surcharge).
Le cluster est désormais opérationnel. Si un serveur primaire tombe en panne, les autres serveurs continueront à fonctionner normalement. Lorsque le serveur primaire sera de nouveau opérationnel, il se synchronisera automatiquement avec les autres.
Pour la gestion du failover, il faut ajouter un proxy comme HAProxy devant nos serveurs MariaDB. Cela permettra de rediriger automatiquement le trafic vers le serveur opérationnel en cas de panne.
On peut également utiliser un système d'IP virtuelle avec Corosync notamment. Il faudrait également prévoir le chiffrement des échanges entre les noeuds, avec un réseau dédié à la synchonisation. Tout cela fera l'objet de mises à jour de ce tutoriel.
Pour tester le fonctionnement du failover, nous allons mettre en place un serveur supplémentaire Wordpress qui va utiliser ce cluster, au travers d'un HAproxy :
On ajoute à notre réseau un nouveau serveur Debian Core:
debianHA
, adresse IP 192.168.1.18/24
On y installe le service HAproxy :
sudo apt update && sudo apt upgrade && sudo apt -y install haproxy
Éditez le fichier de configuration de HAProxy :
sudo nano /etc/haproxy/haproxy.cfg
Remplacer par cette configuration :
# Configuration globale
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin
stats timeout 30s
user haproxy
group haproxy
daemon
defaults
log global
mode tcp # mode TCP pour MariaDB/MySQL
option tcplog
timeout connect 10s
timeout client 1m
timeout server 1m
# Section de monitoring (optionnel)
listen stats
bind *:8404
mode http
stats enable
stats uri /stats
stats realm HAProxy\ Statistics
stats auth admin:password # identifiants pour accéder aux stats
stats refresh 10s
# Section de front pour Galera
frontend mysql_front
bind *:3306
mode tcp
default_backend galera_cluster
# Section de back pour Galera
backend galera_cluster
mode tcp
option tcp-check
balance roundrobin
default-server inter 3s fall 3 rise 2 # contrôle de santé
# Serveurs Galera
server galera1 192.168.1.11:3306 check weight 1
server galera2 192.168.1.12:3306 check weight 1
server galera3 192.168.1.13:3306 check weight 1
inter 3s
définit l’intervalle entre les vérifications (3 secondes).fall 3
signifie que si 3 vérifications échouent, le serveur est marqué comme inactif.rise 2
signifie que le serveur est à nouveau marqué actif après 2 vérifications réussies.Enregistrez le fichier de configuration, puis redémarrez HAProxy pour appliquer les modifications :
sudo systemctl restart haproxy
Vous pouvez accéder aux statistiques de HAProxy en ouvrant un navigateur et en accédant à l'URL http://192.168.1.18:8404/stats
. Utilisez les identifiants définis (admin:password
) pour voir l'état de chaque nœud MariaDB.
On ajoute à notre réseau un nouveau serveur Debian Core:
debianWEB
, adresse IP 192.168.1.20/24
On installe le service nginx (serveur http) ainsi que l'utilitaire wget :
sudo apt update && sudo apt upgrade && sudo apt -y install nginx wget
On installe également le service php-fpm (moteur de script php) :
sudo apt install php-fpm
On repère la version de PHP :
php -v
Ici on aura 8.2 :
PHP 8.2.26 (cli) (built: Nov 25 2024 17:21:51) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.26, Copyright (c) Zend Technologies
with Zend OPcache v8.2.26, Copyright (c), by Zend Technologies
On modifie le fichier de configuration par défaut de nginx :
sudo nano /etc/nginx/sites-available/default
Remplacer par cette configuration simple (adapter au besoin la ligne 11 pour la version de php) :
server {
listen 80 default_server;
root /var/www/html/wordpress;
index index.php index.html index.htm;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
On redémarre le service :
sudo systemctl restart nginx
On récupère le package Wordpress dans le document root :
cd /var/www/html
sudo wget https://wordpress.org/latest.tar.gz
On l'extrait :
sudo tar -xvzf latest.tar.gz
On modifie le propriétaire :
sudo chown -R www-data:www-data wordpress
On installe l'extension php pour mysql :
sudo apt -y install php-mysql
Puis on finalise l’installation de wordpress sur http://192.168.1.20
La base de données n’est pas sur le serveur lui-même (
locahost
) mais bien sur le cluster MariaDB qu’on vient tout juste de configurer, accessible via HAproxy sur192.168.1.18
, avec la base de donnéespascaldb
.
Tout en gardant un oeil sur la page web de monitoring de HAProxy, sur le site wordpress et sur les variable wsrep
, vérifiez l'incidence de l'arrêt d'un des serveurs MariaDB, puis de son redémarrage. Essayer également d'en éteindre deux sur les trois, et de voir la résilience de l'ensemble, au gré des modifications apportées sur le site Wordpress.