Haute disponibilité et résilience dans les bases de données avec MaxScale

Les applications critiques pour la mission nécessitent une haute disponibilité. Le but de la haute disponibilité est de fournir aux utilisateurs un accès constant aux services ou ressources, en minimisant les chances de perturbation. La bascule automatique en cas de défaillance est un mécanisme spécifique utilisé pour atteindre une haute disponibilité. Il implique de détecter automatiquement l’échec d’un composant du système (comme un serveur, un réseau ou une base de données) et de commuter immédiatement les opérations vers un composant de secours sans intervention humaine. Cela augmente la résilience.

MariaDB MaxScale est un proxy de base de données qui comprend des fonctionnalités pour une haute disponibilité. Dans cet article, je vais vous montrer comment vous pouvez l’essayer avec une application de simulateur de boutique en ligne implémentée en Java et Svelte.

Architecture

Le diagramme suivant montre l’architecture de l’application de démonstration :


A web application developed with JavaScript and the Svelte framework makes HTTP requests to a Java backend. The backend answers with server-sent events that the frontend uses to update the user interface on the browser.

L’arrière-plan est réalisé avec Spring Boot et se connecte à un cluster MariaDB en utilisant R2DBC (réactif). La logique arrière-plan est, en bref, une simulation de lectures et d’écritures dans une base de données de boutique en ligne. La simulation est paramétrable, et l’utilisateur peut ajuster :

  • Visites de produits par minute : Combien de lectures dans la base de données par minute.
  • Commandes par minute : Combien d’écritures dans la base de données par minute.
  • Produits par commande: Écriture amplifiée.
  • Délai d’attente en millisecondes: Combien de secondes avant qu’une requête à la base de données soit considérée comme ayant échoué.

Le cluster de base de données est précédé par un proxy de base de données appelé MaxScale. Ce proxy fait paraître le cluster comme une seule base de données logique à l’arrière-plan Java. MaxScale effectue également une séparation lecture/écriture (envoyer les écritures au serveur MariaDB principal et les lectures aux réplicas), ainsi qu’un équilibrage de charge des lectures parmi les serveurs de réplicas à l’aide d’un algorithme configurable. Les données sont automatiquement replicées du serveur principal vers les serveurs de base de données répliqués.

Création des images Docker à partir de la source

I have prepared custom Docker images for every component in the simulator. You can either build the images from the source (optional) or use the already built and published images from Docker Hub. If you decide to build the images yourself, you can find the source code on GitHub:

  • Déploiements MariaDB: Images personnalisées pour un déploiement facile de topologies MariaDB répliquées avec MaxScale. NE PAS UTILISER CECI EN PRODUCTION! Ces images conviennent uniquement pour des applications de démonstration. Utilisez les images Docker officielles MariaDB pour les déploiements en production.
  • Application Backend: L’application backend qui se connecte au cluster de base de données.
  • Application Frontend: L’application frontend qui fait des requêtes de configuration de simulation à l’backend et reçoit des événements pour montrer le résultat de la simulation.

Chaque dépôt possède des Dockerfiles que vous pouvez utiliser pour créer vos propres images Docker. Par exemple, pour construire l’image de l’application backend, exécutez:

Shell

 

docker build --tag alejandrodu/online-store-simulator-java-backend .

Exécution de la Simulation

Tous les services peuvent être lancés en utilisant le fichier Docker Compose suivant (docker-compose.yml) :

YAML

 

version: "3.9"
services:
  server-1:
    container_name: server-1
    image: alejandrodu/mariadb
    ports:
      - "3306:3306"
    environment:
      - MARIADB_CREATE_DATABASE=demo
      - MARIADB_CREATE_USER=user:Password123!
      - MARIADB_CREATE_REPLICATION_USER=replication_user:ReplicationPassword123!
      - MARIADB_CREATE_MAXSCALE_USER=maxscale_user:MaxScalePassword123!

  server-2:
    container_name: server-2
    image: alejandrodu/mariadb
    ports:
      - "3307:3306"
    environment:
      - MARIADB_REPLICATE_FROM=replication_user:ReplicationPassword123!@server-1:3306

  server-3:
    container_name: server-3
    image: alejandrodu/mariadb
    ports:
      - "3308:3306"
    environment:
      - MARIADB_REPLICATE_FROM=replication_user:ReplicationPassword123!@server-1:3306

  maxscale:
    container_name: maxscale
    image: alejandrodu/mariadb-maxscale
    command: --admin_host 0.0.0.0 --admin_secure_gui false
    ports:
      - "4000:4000"
      - "8989:8989"
      - "27017:27017"
    environment:
      - MAXSCALE_USER=maxscale_user:MaxScalePassword123!
      - MARIADB_HOST_1=server-1 3306
      - MARIADB_HOST_2=server-2 3306
      - MARIADB_HOST_3=server-3 3306
    healthcheck:
      test: ["CMD", "maxctrl", "list", "servers"]
      interval: 5s
      timeout: 10s
      retries: 5

  java-backend:
    container_name: java-backend
    image: alejandrodu/online-store-simulator-java-backend
    ports:
      - "8080:8080"
    environment:
    - spring.r2dbc.url=r2dbc:mariadb://maxscale:4000/demo
    - spring.r2dbc.username=user
    - spring.r2dbc.password=Password123!
    - spring.liquibase.url=jdbc:mariadb://maxscale:4000/demo
    - spring.liquibase.user=user
    - spring.liquibase.password=Password123!
    depends_on:
      maxscale:
        condition: service_healthy

  svelte-frontend:
    container_name: svelte-fronted
    image: alejandrodu/online-store-simulator-svelte-frontend
    ports:
      - "5173:80"
    environment:
      - BACKEND_URL=http://java-backend:8080

Allez dans le répertoire où se trouve le fichier Docker Compose, et démarrez les services en mode détaché comme suit:

Shell

 

docker compose up -d

Configuration de MaxScale

Avant de démarrer la simulation, configurez MaxScale pour la relecture de transactions. Aussi, ajustez les délais d’attente pour rendre la simulation plus intéressante.

Naviguez vers http://localhost:8989/ et connectez-vous à l’interface utilisateur en utilisant :

  • Nom d’utilisateur :admin
  • Mot de passe :mariadb

Vous verrez un tableau de bord avec l’état du cluster MariaDB.


Il y a un serveur principal (server-1), et deux réplicas (server-2 et server-3). La réplication est déjà configurée de server-1 (principal) vers server-2 et server-3 (réplicas). Tous les serveurs devraient être en cours d’exécution.

Cliquez sur mdb_monitor puis sur l’icône crayon pour activer la modification des paramètres. Définissez les paramètres suivants :

  • auto_failover (true) : Cela active le basculement automatique. Lorsqu’un serveur MariaDB est hors ligne, MaxScale sélectionne un serveur réplica et le reconfigure en tant que nouveau serveur principal afin que les écritures puissent continuer.
  • auto_rejoin (true) : Cela active le retour automatique des serveurs récupérés. Lorsqu’un serveur en échec est à nouveau opérationnel, MaxScale le détecte et le configure en tant que serveur réplica disponible.
  • failcount (1) : Définit le nombre d’itérations du moniteur (un composant dans MaxScale qui vérifie l’état du serveur) nécessaires pour qu’un serveur soit considéré comme en panne afin d’activer le processus de basculement. Nous définissons une valeur de 1 pour nous assurer que le basculement commence immédiatement après l’échec.
  • backend_connect_timeout (1000) : Délai de connexion pour les connexions du moniteur. Nous définissons une valeur faible (une seconde) pour activer rapidement le basculement pour cette démonstration.
  • backend_read_timeout (1000) : Délai d’attente pour la lecture des connexions de surveillance.
  • backend_write_timeout (1000) : Délai d’attente pour l’écriture des connexions de surveillance.
  • master_failure_timeout (1000) : Délai d’attente pour la défaillance du maître.
  • monitor_interval (1000) : Fréquence à laquelle les serveurs sont surveillés.

ATTENTION: Ces valeurs conviennent pour cette démo mais très probablement pas les meilleures pour les environnements de production !

Une fois les paramètres définis, cliquez sur Terminé la modification et Confirmer.

Vous devez également activer la reprise des transactions qui réexécute automatiquement les transactions en cours ayant échoué sur les serveurs qui sont tombés juste après qu’une instruction SQL a été acheminée. C’est une fonctionnalité utile pour les développeurs de logiciels car elle évite la nécessité de coder des cas de défaillance et de reprise de transaction.

Dans le menu principal, cliquez sur Tableau de bord puis sur l’un des liens service_de_routage_de_requêtes dans la liste des serveurs. Modifiez les paramètres comme suit :

  • transaction_replay (true) : Active la reprise automatique des transactions ayant échoué.
  • transaction_replay_retry_on_deadlock (true) : Même chose que précédemment en cas de verrouillage.
  • transaction_replay_retry_on_mismatch (true) : Même chose que précédemment en cas de déséquilibre de somme de contrôle.

Une fois les paramètres définis, cliquez sur Terminé la modification et Confirmer.

Démarrage de la Simulation

Avec tout configuré, vous pouvez démarrer la simulation. Rendez-vous à http://localhost:5173/ et configurez les paramètres suivants (les noms sont, j’espère, parlants) :

  • Visites de produits par minute :6000
  • Commandes par minute :60
  • Timeout en millisecondes :8000

Mais avant de démarrer la simulation, vous devez créer les produits pour le magasin en ligne. Cliquez sur Données | Créer des produits…. Laissez les valeurs par défaut et cliquez sur Créer. Vous devriez voir l’interface utilisateur se mettre à jour au fur et à mesure que les produits sont créés dans la base de données.

Vous pouvez maintenant enfin cliquer sur Démarrer et voir la simulation en action.


Simulation d’un échec du serveur

À ce stade, le serveur principal gère les écritures (commandes). Que se passe-t-il si vous arrêtez ce serveur ? Dans la ligne de commande, exécutez :

Shell

 

docker stop server-1

En fonction de divers facteurs, vous pourriez avoir quelques « visiteurs déçus » ou même quelques « occasions manquées » dans le simulateur. Ou peut-être n’en n’obtenez-vous aucune ! Les visites de produits (lectures) et les commandes (écritures) continuent d’arriver grâce à MaxScale. Sans basculement automatique, vous devez reconfigurer tout manuellement, ce qui se traduit par plus de temps hors ligne et de nombreux visiteurs déçus et opportunités manquées !

Démarrez le serveur en échec :

Shell

 

docker start server-1

Allez sur le Tableau de bord MaxScale (http://localhost:8989/) et vérifiez que server-1 est désormais une réplique fonctionnelle.

Vous pouvez effectuer une commutation manuelle pour remettre serveur-1 en tant que serveur principal. Cliquez sur mdb_monitor puis placez le curseur sur la section MASTER. Cliquez sur l’icône crayon et sélectionnez serveur-1. Cliquez sur Échanger et vérifiez à nouveau dans le Tableau de bord que le nouveau serveur principal est serveur-1.

Conclusion

La bascule automatique n’est qu’un des composants des systèmes hautement disponibles. Vous pouvez utiliser un proxy de base de données comme MaxScale pour mettre en place une bascule automatique, mais aussi d’autres composants tels que la répartition de charge, la routage de requêtes, la reprise de transactions, l’isolation topologique, et bien plus encore. Consultez la documentation ici.

Source:
https://dzone.com/articles/high-availability-and-resiliency-in-databases