Dimensionierung und Leistung
Typischerweise entfallen im TCP- oder HTTP-Close-Modus 15% der Verarbeitungszeit auf HAProxy und 85% auf den Kernel. Im HTTP-Keep-Alive-Modus sind es etwa 30% für HAProxy und 70% für den Kernel. Betriebssystem und Systemoptimierung beeinflussen die Gesamtleistung daher stark.
Die Anforderungen unterscheiden sich erheblich: Manche Nutzer konzentrieren sich auf Bandbreite, andere auf Anfragerate, gleichzeitige Verbindungen oder SSL-Leistung. Dieser Abschnitt gibt einige Anhaltspunkte für die Planung.
Jede Operation verursacht Aufwand, der sich zum Aufwand der übrigen Operationen addiert. Unter bestimmten Umständen ist er vernachlässigbar, unter anderen kann er überwiegen.
Für die Verarbeitung von Anfragen einer Verbindung gilt:
-
Das Weiterleiten von Daten kostet weniger als das Auswerten von Anfrage- oder Antwort-Headern;
-
das Auswerten von Anfrage- oder Antwort-Headern kostet weniger als der Aufbau und anschließende Abbau einer Verbindung zu einem Server;
-
Aufbau und Abbau einer Verbindung kosten weniger als die Wiederaufnahme einer TLS-Sitzung;
-
die Wiederaufnahme einer TLS-Sitzung kostet weniger als ein vollständiger TLS-Handshake mit Schlüsselberechnung;
-
eine untätige Verbindung benötigt weniger CPU-Leistung als eine Verbindung mit Daten in ihren Puffern;
-
ein TLS-Kontext benötigt noch mehr Speicher als eine Verbindung mit Daten;
In der Praxis ist die Verarbeitung von Nutzdatenbytes somit günstiger als die von Headerbytes. Hohe Netzwerkbandbreiten lassen sich deshalb mit großen Objekten, also wenigen Anfragen pro Datenmenge, leichter erreichen als mit kleinen Objekten und entsprechend vielen Anfragen. Daher wird die maximale Bandbreite immer mit großen Objekten gemessen, die Anfrage- und Verbindungsraten dagegen mit kleinen.
Manche Operationen skalieren gut über mehrere Prozesse auf mehreren CPUs, andere weniger gut. Die Netzwerkbandbreite lässt sich nur begrenzt steigern, da bei großen Objekten selten die CPU den Engpass bildet. Meist begrenzen die Netzwerkbandbreite und die Datenbusse zu den Netzwerkschnittstellen. Die Verbindungsrate skaliert wegen einiger Sperren beim Zugriff auf die lokale Porttabelle des Systems schlecht über mehrere Prozessoren. Die Anfragerate über dauerhafte Verbindungen skaliert dagegen sehr gut: Sie benötigt wenig Speicher und Netzwerkbandbreite und keinen Zugriff auf gesperrte Strukturen. Auch die TLS-Schlüsselberechnung skaliert sehr gut, da sie vollständig CPU-gebunden ist. Die Wiederaufnahme von TLS-Sitzungen skaliert mäßig gut und erreicht ihre Grenzen bei etwa 4 Prozessen. Danach gleicht der Aufwand für den Zugriff auf die gemeinsame Tabelle die geringen zusätzlichen Leistungsgewinne aus.
Ein sehr gut optimiertes System erreicht ungefähr die folgenden Leistungswerte. Sie sind als Größenordnungen zu verstehen. Je nach Prozessor, IRQ-Einstellungen, Speichertyp, Netzwerkschnittstelle, Betriebssystemoptimierung und weiteren Faktoren sind erhebliche Abweichungen in beide Richtungen zu erwarten.
Die folgenden Werte wurden mit einem Core i7 bei 3.7 GHz, einer Netzwerkkarte (NIC) mit zwei 10-Gbps-Ports, Linux-Kernel 3.10, HAProxy 1.6 und OpenSSL 1.0.2 ermittelt. HAProxy lief als einzelner Prozess auf einem exklusiv zugewiesenen CPU-Kern; zwei weitere Kerne waren für Netzwerk-Interrupts reserviert:
-
20 Gbps maximale Netzwerkbandbreite bei unverschlüsselter Übertragung von Objekten ab 256 kB, 10 Gbps bei Objekten ab 41kB;
-
4.6 Gbps TLS-Datenverkehr mit AES256-GCM und großen Objekten;
-
83000 TCP-Verbindungen pro Sekunde vom Client zum Server;
-
82000 HTTP-Verbindungen pro Sekunde vom Client zum Server;
-
97000 HTTP-Anfragen pro Sekunde im Server-Close-Modus, also Keep-Alive zum Client und Schließen der Verbindung zum Server;
-
243000 HTTP-Anfragen pro Sekunde mit durchgehendem Keep-Alive;
-
300000 gefilterte TCP-Verbindungen pro Sekunde zur DDoS-Abwehr
-
160000 HTTPS-Anfragen pro Sekunde im Keep-Alive-Modus über dauerhafte TLS-Verbindungen;
-
13100 HTTPS-Anfragen pro Sekunde mit wiederaufgenommenen TLS-Verbindungen;
-
1300 HTTPS-Verbindungen pro Sekunde mit jeweils neu ausgehandeltem TLS und RSA2048;
-
20000 gleichzeitige, voll ausgelastete Verbindungen pro GB RAM einschließlich des Speichers für Systempuffer; mit sorgfältiger Optimierung sind bessere Werte möglich, dieser Wert ist jedoch leicht zu erreichen.
-
etwa 8000 gleichzeitige TLS-Verbindungen nur auf der Clientseite pro GB RAM einschließlich des Speichers für Systempuffer;
-
etwa 5000 gleichzeitige durchgehende TLS-Verbindungen auf beiden Seiten pro GB RAM einschließlich des Speichers für Systempuffer;
Ein neuerer Benchmark mit HAProxy 2.4 im Mehrthreadbetrieb auf einem ARM-Graviton2-Prozessor mit 64 Kernen bei AWS erreichte 2 Millionen HTTPS-Anfragen pro Sekunde bei Antwortzeiten unter einer Millisekunde und 100 Gbps Datenverkehr:
Als Faustregel sinkt die Anfragerate von TLS-Keep-Alive zur TLS-Wiederaufnahme sowie von der TLS-Wiederaufnahme zur TLS-Neuaushandlung jeweils um den Faktor 10. Zwischen HTTP-Keep-Alive und HTTP-Close sinkt sie dagegen nur um den Faktor 3. Eine weitere Faustregel: Ein hoch getakteter Kern mit AES-Befehlen schafft etwa 20 Gbps AES-GCM pro Kern.
Eine weitere nützliche Faustregel ist, dass HAProxy auf derselben Serverhardware etwa folgende Anzahl von Servern vollständig auslasten kann:
-
etwa 5-10 Server für statische Dateien oder Caching-Proxys;
-
etwa 100 Antivirus-Proxys;
-
etwa 100-1000 Anwendungsserver, abhängig von der verwendeten Technologie.