Planung einer Multi-Server-Architektur für dedizierte Infrastruktur

Leitfaden zur Planung einer Multi-Server-Architektur für dedizierte Infrastruktur

Ein einzelner dedizierter Server reicht für die meisten Webanwendungen in der Produktion völlig aus. Irgendwann reicht er jedoch nicht mehr aus – entweder, weil das Datenaufkommen so stark angestiegen ist, dass ein einzelner Server es nicht mehr bewältigen kann, weil du Redundanz benötigst, damit ein Hardwareausfall die Anwendung nicht lahmlegt, oder weil deine Datenbank so groß geworden ist, dass sie auf dedizierter Hardware laufen sollte…

Wenn ein einzelner Server nicht mehr die richtige Lösung ist

Die Auslöser für den Umstieg auf eine Multi-Server-Architektur sind ganz konkret. Die allgemeine Begründung „Wir wachsen“ reicht nicht aus – die Kosten und die Komplexität einer Multi-Server-Infrastruktur sind real, und die Optimierung eines einzelnen Servers verlängert die Laufzeit oft weiter, als die Teams erwarten.

Wechsle zur Multi-Server-Architektur, wenn:

  • Die durchschnittliche Auslastung liegt während der normalen Spitzenzeiten durchgehend über deiner Kernanzahl, nicht nur bei Spitzenauslastungen. Ein Server mit 16 Kernen und einer anhaltenden durchschnittlichen Auslastung von über 20 stellt Aufgaben in die Warteschlange.
  • Deine Datenbank und deine Anwendung konkurrieren um denselben Arbeitsspeicher. Redis-Caching, der MySQL-InnoDB-Pufferpool, PHP-FPM-Worker und der Anwendungsspeicher teilen sich auf einem einzelnen Server denselben physischen Arbeitsspeicher. Irgendwann stehen sich die Leistung der Datenbank und die Leistung der Webschicht in einem direkten Spannungsverhältnis gegenüber.
  • Ein Hardwareausfall wäre ein Betriebsvorfall. Wenn dir Ausfallzeiten des Servers während des Austauschs (in der Regel 2–4 Stunden) erhebliche Kosten verursachen würden, brauchst du Redundanz.
  • Die Bereitstellung erfordert Ausfallzeiten. Bei Konfigurationen mit mehreren Servern sind schrittweise Bereitstellungen möglich; bei Bereitstellungen auf einem einzelnen Server muss die Anwendung während der Aktualisierung oft offline genommen werden.

Stufe 1: Trennung von Web und Datenbank

Die erste sinnvolle Mehrserver-Konfiguration trennt die Webanwendungsschicht von der Datenbankschicht. Dadurch wird das Problem der RAM-Konkurrenz gelöst und jeder Server kann für seine jeweilige Rolle optimiert werden.

Webserver: Nginx, PHP-FPM, Anwendungscode, Redis-Cache. CPU-optimierte Konfiguration. Die Essential- oder Elite-Tarife von InMotion eignen sich in dieser Phase für die meisten Anwendungen.

Datenbankserver:PostgreSQL, großer InnoDB-Pufferpool (70–80 % des Arbeitsspeichers), optimierte Festplatten-E/A-Konfiguration. Speicheroptimierte Konfiguration. Mit seinen 192 GB DDR5-RAM eignet sich der Extreme-Server hervorragend als dedizierter Datenbankserver – ein InnoDB-Pufferpool von 130–150 GB sorgt dafür, dass die meisten Produktionsdatenbanken vollständig im Arbeitsspeicher verbleiben.

Die Netzwerkverbindung zwischen den beiden Servern ist entscheidend. Beide Server sollten im selben InMotion-Rechenzentrum bereitgestellt werden, um eine private Netzwerkkommunikation mit geringer Latenz zu gewährleisten. In der Anwendungskonfiguration werden die Datenbankverbindungen auf die private IP-Adresse des Datenbankservers statt auf „localhost“ gerichtet:

// WordPress wp-config.php

define('DB_HOST', '10.0.0.2'); // Database server private IP

define('DB_NAME', 'production_db');

define('DB_USER', 'app_user');

define('DB_PASSWORD', 'secure_password');

MySQL on the database server should bind to the private interface and accept connections only from the web server IP:

# /etc/mysql/mysql.conf.d/mysqld.cnf

bind-address = 10.0.0.2

# Grant access only from web server

# GRANT ALL ON production_db.* TO 'app_user'@'10.0.0.1' IDENTIFIED BY 'password';

Ebene 2: Web-Ebene mit Lastenausgleich

Wenn ein einzelner Webserver nicht mehr ausreicht, sorgt das Hinzufügen eines zweiten Webservers hinter einem Load Balancer für eine Verteilung des Datenverkehrs und bietet eine Ausfallsicherung, falls ein Webserver ausfällt.

HAProxy ist der Standard-Open-Source-Load-Balancer für diese Konfiguration. Er läuft auf einem kleinen Server (oder auf dem Datenbankserver, sofern die Ressourcen dies zulassen) und verteilt Anfragen auf die Web-Ebene:

global

    maxconn 50000

    log /dev/log local0

defaults

    mode http

    timeout connect 5s

    timeout client 30s

    timeout server 30s

    option httplog

frontend web_frontend

    bind *:80

    bind *:443 ssl crt /etc/ssl/certs/production.pem

    default_backend web_servers

backend web_servers

    balance roundrobin

    option httpchk GET /health

    server web1 10.0.0.1:80 check inter 2s

    server web2 10.0.0.2:80 check inter 2s

Die Option „httpchk“ sendet alle 2 Sekunden Health-Check-Anfragen an „/health“ auf jedem Webserver. Ein Server, der die Health-Checks nicht besteht, wird automatisch aus der Rotation entfernt. Die Konfigurationsanleitung von HAProxy behandelt die gesamte Health-Check-Konfiguration, einschließlich der Abgleichung von Antwortcodes und der Fehlergrenzen.

Der Sitzungsstatus muss außerhalb der Webserver gespeichert werden. Wenn der Lastausgleich Anfragen auf mehrere Webserver verteilt, kann jede Anfrage auf einem anderen Server landen. Sitzungsdaten, die im standardmäßigen dateibasierten Sitzungshandler von PHP gespeichert sind, stehen auf dem anderen Server nicht zur Verfügung. Speichere Sitzungen in Redis auf dem Datenbankserver:

# /etc/php/8.x/fpm/php.ini

session.save_handler = redis

session.save_path = "tcp://10.0.0.3:6379"

Alle Webserver verweisen auf dieselbe Redis-Instanz. Jeder Webserver kann jede Anfrage bearbeiten, unabhängig davon, welcher Server vorherige Anfragen desselben Nutzers bearbeitet hat.

Stufe 3: Hochverfügbarkeit der Datenbank

Eine Redundanz auf Web-Ebene ohne Datenbank-Redundanz führt zu einem Single Point of Failure auf der Datenbankebene. MySQL-Replikation oder -Clustering sorgt für Redundanz auf Datenbankebene.

Die MySQL-Primär-Replik-Replikation ist die einfachste Hochverfügbarkeitskonfiguration. Der Primärserver verarbeitet alle Schreibvorgänge; die Replikate erhalten Änderungen über die Binlog-Replikation und können Leseabfragen bearbeiten.

# Primary server my.cnf

[mysqld]

server-id = 1

log_bin = /var/log/mysql/mysql-bin.log

binlog_format = ROW

sync_binlog = 1

innodb_flush_log_at_trx_commit = 1

# Replica server my.cnf

[mysqld]

server-id = 2

relay-log = /var/log/mysql/relay-bin.log

read_only = 1

Für das automatische Failover (d. h. die Umwandlung einer Replik in den Primärserver, falls dieser ausfällt) ist Orchestrator das Standardwerkzeug für die Verwaltung der MySQL-Topologie. Orchestrator überwacht die Replikationstopologie und kann automatische Umwandlungen durchführen, wobei Integrationen mit Consul oder ZooKeeper für die DNS-basierte Failover-Koordination zur Verfügung stehen.

MySQL InnoDB Cluster bietet synchrone Replikation mit automatischem Failover, allerdings auf Kosten einer höheren Schreiblatenz (Schreibvorgänge müssen von einem Quorum von Knoten bestätigt werden, bevor sie festgeschrieben werden). Für Anwendungen, bei denen Datenverlust beim Failover nicht akzeptabel ist, bietet das synchrone Modell von InnoDB Cluster stärkere Garantien als die asynchrone Replikation. Die Dokumentation zu MySQL Group Replication behandelt die Einrichtung und betriebliche Überlegungen.

Architekturdiagramm: Produktionsumgebung mit drei Servern

[Load Balancer / HAProxy]

                         10.0.0.0:80,443

                        /               \

              [Web Server 1]         [Web Server 2]

               10.0.0.1               10.0.0.2

               Nginx + PHP            Nginx + PHP

                        \               /

                    [Database Server]

                         10.0.0.3

                    MySQL Primary + Redis

                         |

                    [DB Replica]

                         10.0.0.4

                    MySQL Replica

Diese Konfiguration deckt Folgendes ab:

  • Ausfall der Web-Ebene: HAProxy entfernt den ausgefallenen Webserver; der verbleibende Server übernimmt den gesamten Datenverkehr
  • Fehler bei der Datenbankreplikation: Die Anwendung schreibt weiterhin auf den Primärserver; die Replik stellt die Verbindung wieder her und holt den Rückstand auf
  • Ausfall des primären Datenbankservers: Der Orchestrator erhebt die Replik zur primären Instanz; DNS-Updates leiten die Anwendung auf den neuen primären Server um

Was es nicht abdeckt: Ausfall des Load Balancers. Durch das Hinzufügen von HAProxy-Redundanz mit Keepalived (für das VIP-Failover zwischen zwei HAProxy-Instanzen) wird dieser letzte Single Point of Failure beseitigt.

Gemeinsamer Dateispeicher für mehrere Webserver

Webanwendungen, die das Hochladen von Dateien ermöglichen (Bilder, Dokumente, nutzergenerierte Inhalte), benötigen diese Dateien auf allen Webservern. Dateien, die auf web1 hochgeladen werden, müssen auf web2 lesbar sein.

Drei Ansätze, geordnet nach Komplexität:

NFS-Einbindung: Ein Server stellt ein Verzeichnis über NFS bereit; andere binden es ein. Einfach, aber der NFS-Server wird bei steigendem Umfang zum Single Point of Failure und zu einem I/O-Engpass.

GlusterFS: Ein verteiltes Dateisystem, das Daten auf mehrere Server repliziert. Die Konfiguration ist etwas aufwendiger, dafür wird der Single Point of Failure vermieden.

Objektspeicher mit CDN-Frontend: Lade Dateien direkt in einen S3-kompatiblen Objektspeicher (oder den Backup-Speicher von InMotion als Staging-Bereich) hoch und stelle sie über das CDN bereit. Die übersichtlichste Architektur für neue Anwendungen – kein gemeinsames Dateisystem, das verwaltet werden muss.

Bei bestehenden Anwendungen ist NFS oft der schnellste Weg zum Dateizugriff über mehrere Server hinweg. Bei Anwendungen, die von Anfang an für den Einsatz auf mehreren Servern konzipiert sind, lässt sich durch Objektspeicher mit CDN-Bereitstellung eine ganze Reihe von betrieblichen Komplexitäten von vornherein vermeiden.

Den Ablauf planen

Eine Multi-Server-Architektur muss nicht auf einmal implementiert werden. Der typische Ablauf:

  1. Beginne mit einem gut konfigurierten Einzelserver (InMotion Essential oder Extreme, je nach Arbeitslast)
  2. Verlege die Datenbank auf einen eigenen Server, sobald es zu messbaren RAM- oder E/A-Engpässen kommt
  3. Füge einen zweiten Webserver und einen Load Balancer hinzu, wenn die CPU-Auslastung konstant hoch ist
  4. Füge eine Datenbankreplikation hinzu, wenn geschäftliche Anforderungen ein geringeres Ausfallrisiko erfordern
  5. Füge HAProxy-Redundanz hinzu, wenn der Load Balancer selbst zum letzten Single Point of Failure wird

Jeder Schritt verursacht zusätzliche Kosten und erhöht die Komplexität der Abläufe. Wechsle erst dann zur nächsten Stufe, wenn die aktuellen Einschränkungen messbar sind – und nicht in Erwartung von Einschränkungen, die noch gar nicht eingetreten sind.

Weiterführende Literatur: Hybride Infrastruktur: Kombination aus dedizierten Systemen und Cloud | Überwachung von Serverressourcen und Leistungsoptimierung

Diesen Artikel teilen

Eine Antwort hinterlassen

Deine E-Mail Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert