Hochverfügbarkeit und Robustheit in Datenbanken mit MaxScale

Mission-kritische Anwendungen erfordern hohe Verfügbarkeit. Das Ziel der hohen Verfügbarkeit besteht darin, den Nutzern konsistenten Zugriff auf Dienste oder Ressourcen zu gewährleisten und die Wahrscheinlichkeit von Unterbrechungen zu minimieren. Automatisches Failover ist ein spezielles Verfahren zur Erreichung der hohen Verfügbarkeit. Es beinhaltet das automatische Erkennen eines Ausfalls eines Systemkomponenten (wie eines Servers, einer Netzwerkverbindung oder einer Datenbank) und das sofortige Übertragen der Betriebsabläufe auf eine Ersatzkomponente ohne menschliche Intervention. Dies erhöht die Robustheit.

MariaDB MaxScale ist ein Datenbank-Proxy, der Funktionen für hohe Verfügbarkeit enthält. In diesem Artikel werde ich Ihnen zeigen, wie Sie es mit einer Online-Shop-Simulationsanwendung aus Java und Svelte ausprobieren können.

Architektur

Das folgende Diagramm zeigt die Architektur der Demo-Anwendung:


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.

Die Backend-Implementierung erfolgt mit Spring Boot und verbindet sich mit einem MariaDB-Datenbankcluster unter Verwendung von R2DBC (reaktiv). Die Backend-Logik ist kurz gesagt eine Simulation von Lese- und Schreibvorgängen in einer Online-Shop-Datenbank. Die Simulation ist parametrisiert und der Benutzer kann einstellen:

  • Produktbesuche pro Minute: Wie viele Lesevorgänge pro Minute in der Datenbank.
  • Bestellungen pro Minute: Wie viele Schreibvorgänge pro Minute in der Datenbank.
  • Produkte pro Bestellung: Schreibverstärkung.
  • Timeout in Millisekunden: Wie viele Sekunden vergehen müssen, bis eine Anfrage an die Datenbank als fehlgeschlagen betrachtet wird.

Die Datenbank-Cluster wird von einem Datenbank-Proxy namens MaxScale vorgelagert. Dieser Proxy lässt den Cluster für die Java-Backend-Anwendung wie eine einzige logische Datenbank erscheinen. MaxScale führt auch Lesen/Schreiben Aufteilung durch (Senden von Schreibvorgängen an den primären MariaDB-Server und Lesevorgängen an die Replikate), sowie Lastverteilung von Lesevorgängen unter den Replikatservern mithilfe eines konfigurierbaren Algorithmus. Die Daten werden automatisch repliziert vom primären zum Replikat-Datenbankserver.

Erstellung der Docker-Images aus dem Quellcode

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:

  • MariaDB-Bereitstellungen: Benutzerdefinierte Images zur einfachen Bereitstellung von replizierten MariaDB-Topologien mit MaxScale. NUTZEN SIE DIESE NICHT IN PRODUKTION! Diese Images sind nur für Demo-Anwendungen geeignet. Verwenden Sie die offiziellen MariaDB Docker-Images für Produktionsbereitstellungen.
  • Backend-Anwendung: Die Backend-Anwendung, die mit dem Datenbank-Cluster verbunden ist.
  • Frontend-Anwendung: Die Frontend-Anwendung, die Konfigurationsanfragen für die Simulation an das Backend sendet und Ereignisse empfängt, um das Simulationsergebnis anzuzeigen.

Jeder Repository enthält Dockerfiles, die Sie verwenden können, um Ihre eigenen Docker-Images zu erstellen. Um beispielsweise das Backend-Anwendungs-Image zu erstellen, führen Sie:

Shell

 

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

Durchführung der Simulation

Alle Dienste können mithilfe der folgenden Docker Compose-Datei (docker-compose.yml) gestartet werden:

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

Wechseln Sie in das Verzeichnis, in dem die Docker Compose-Datei ist, und starten Sie die Dienste im getrennten Modus wie folgt:

Shell

 

docker compose up -d

Konfiguration von MaxScale

Bevor Sie die Simulation starten, konfigurieren Sie MaxScale für Transaktionswiederholung. Auch stellen Sie Timeouts ein, um die Simulation interessanter zu gestalten.

Navigieren Sie zu http://localhost:8989/ und melden Sie sich in der Benutzeroberfläche mit:

  • Benutzername:admin
  • Passwort:mariadb

Sie sehen ein Dashboard mit dem Status des MariaDB-Clusters.


Es gibt einen primären Server (server-1), und zwei Replikate (server-2 und server-3). Die Replikation ist bereits von server-1 (primär) zu server-2 und server-3 (Replikate) konfiguriert. Alle Server sollten ausgeführt werden.

Klicken Sie auf mdb_monitor und dann auf das Stiftsymbol zum Aktivieren der Parameterbearbeitung. Setzen Sie die folgenden Parameter:

  • auto_failover (true): Dies aktiviert den automatischen Failover. Wenn ein MariaDB-Server ausfällt, wählt MaxScale ein Replikatserver aus und konfiguriert diesen als neuen primären Server, damit die Schreibvorgänge fortgesetzt werden können.
  • auto_rejoin (true): Dies aktiviert die automatische Wiederkehr von wiederhergestellten Servern. Wenn ein ausgefallener Server wieder online ist, erkennt MaxScale dies und konfiguriert ihn als verfügbares Replikatserver.
  • failcount (1): Legt die Anzahl der Monitorereignisse (ein Komponente in MaxScale, die den Serverstatus überprüft) fest, die für einen Server erforderlich sind, um als ausgefallen zu gelten, um den Failover-Prozess zu aktivieren. Wir setzen einen Wert von 1 um sicherzustellen, dass der Failover sofort nach dem Ausfall beginnt.
  • backend_connect_timeout (1000): Verbindungszeitüut für Monitorverbindungen. Wir setzen einen niedrigen Wert (eine Sekunde) um schnell den Failover für diese Demo zu aktivieren.
  • backend_read_timeout (1000): Lesezeitüberschreitung für Überwachungskonnektivitäten.
  • backend_write_timeout (1000): Schreibzeitüberschreitung für Überwachungskonnektivitäten.
  • master_failure_timeout (1000): Primärzeitüberschreitung.
  • monitor_interval (1000): Wie häufig die Server überwacht werden.

WARNUNG: Diese Werte sind für diese Demo geeignet, aber sehr wahrscheinlich nicht die besten für Produktionsumgebungen!

Sobald die Parameter eingestellt sind, klicken Sie auf Fertig Bearbeiten und Bestätigen.

Sie müssen auch die Transaktionswiederholung aktivieren, die fehlgeschlagene laufende Transaktionen automatisch auf Servern, die direkt nach einer SQL-Anweisung geroutet wurden, wiederholt. Dies ist eine nützliche Funktion für Softwareentwickler, da es die Notwendigkeit zur Kodierung von Fehlerfällen und Transaktionswiederholungen verhindert.

Klicken Sie im Hauptmenü auf Übersicht und dann auf einen der query_router_service Links in der Liste der Server. Bearbeiten Sie die Parameter wie folgt:

  • transaction_replay (true): Aktiviert die automatische Wiederholung fehlgeschlagener Transaktionen.
  • transaction_replay_retry_on_deadlock (true): Gleich wie zuvor bei einem Deadlock.
  • transaction_replay_retry_on_mismatch (true): Gleich wie zuvor bei einer Prüfsummenabweichung.

Sobald die Parameter eingestellt sind, klicken Sie auf Fertig Bearbeiten und Bestätigen.

Starten der Simulation

Mit allen Konfigurationen können Sie die Simulation beginnen. Navigieren Sie zu http://localhost:5173/ und konfigurieren Sie die folgenden Parameter (die Namen sollten, hoffe ich, selbsterklärend sein):

  • Produktbesuche pro Minute:6000
  • Bestellungen pro Minute:60
  • Timeout in Millisekunden:8000

Bevor Sie die Simulation starten, müssen Sie jedoch die Produkte für den Onlineshop erstellen. Klicken Sie auf Daten | Produkte erstellen…. Lassen Sie die Standardwerte und klicken Sie auf Erstellen. Sie sollten die Benutzeroberfläche aktualisieren sehen, wenn Produkte in der Datenbank erstellt werden.

Jetzt können Sie endlich auf Start klicken und die Simulation in Aktion sehen.


Simulation eines Serverausfalls

An diesem Punkt bearbeitet der primäre Server Schreibvorgänge (Bestellungen). Was passiert, wenn Sie diesen Server stoppen? Führen Sie im Kommandozeilenfenster aus:

Shell

 

docker stop server-1

Abhängig von mehreren Faktoren könnten Sie einige „enttäuschte Besucher“ oder sogar einige „verpasste Chancen“ im Simulator erhalten. Oder vielleicht erhalten Sie gar keine! Produktbesuche (Lesevorgänge) und Bestellungen (Schreibvorgänge) finden weiterhin statt, dank MaxScale. Ohne automatischen Failover müssen Sie alles manuell neu konfigurieren, was zu mehr Offline-Zeit und in vielen Fällen zu enttäuschten Besuchern und verpassten Gelegenheiten führt!

Starten Sie den fehlerhaften Server:

Shell

 

docker start server-1

Gehen Sie zum MaxScale Dashboard (http://localhost:8989/) und überprüfen Sie, dass server-1 jetzt eine funktionierende Replica ist.

Sie können eine manuelle Umstellung durchführen, um server-1 wieder als primären Server zu machen. Klicken Sie auf mdb_monitor und bewegen Sie den Mauszeiger über den MASTER Abschnitt. Klicken Sie auf das Stiftsymbol und wählen Sie server-1. Klicken Sie auf Tauschen und überprüfen Sie im Dashboard, ob der neue primäre Server server-1 ist.

Schlussfolgerung

Automatisches Failover ist nur einer der Bestandteile in hochverfügbaren Systemen. Sie können einen Datenbank-Proxy wie MaxScale verwenden, um ein automatisches Failover einzurichten, aber auch andere Komponenten wie Lastverteilung, Abfrage-Routing, Transaktionswiederholung, Topologieisolation und mehr. Schauen Sie sich die Dokumentation hier an.

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