Auswahl Ihres PostgreSQL Connection Proxy
James Reed
Infrastructure Engineer · Leapcell

Einleitung: Der unsichtbare Held der Datenbankleistung
In der Welt der Hochleistungsanwendungen ist der Datenbankzugriff oft ein kritischer Engpass. Jede neue Verbindung zu einer PostgreSQL-Datenbank verursacht Overhead – Authentifizierung, Prozesserstellung und Ressourcenallokation. Bei Anwendungen mit häufigen, kurzlebigen Verbindungen kann dieser Overhead schnell die Leistung mindern und Serverressourcen erschöpfen. Stellen Sie sich eine beliebte E-Commerce-Website während eines Flash-Sales vor; Tausende von Benutzern versuchen gleichzeitig, sich zu verbinden. Ohne einen Mechanismus zur effizienten Verwaltung dieser Verbindungen würde die Datenbank Schwierigkeiten haben, Schritt zu halten. Hier kommen Connection-Pooling-Proxies ins Spiel, die sich zwischen Ihrer Anwendung und dem PostgreSQL-Server befinden und vorhandene Verbindungen intelligent wiederverwenden, anstatt für jede Anfrage neue herzustellen. Sie fungieren als lautlos effiziente Gatekeeper, die Skalierbarkeit und Reaktionsfähigkeit dramatisch verbessern. Zwei herausragende Open-Source-Lösungen zeichnen sich in der PostgreSQL-Umgebung durch diese wichtige Rolle aus: PgBouncer und Pgpool-II. Das Verständnis ihrer Feinheiten ist entscheidend für die Optimierung Ihrer Datenbankinfrastruktur, und dieser Artikel führt Sie durch ihre jeweiligen Stärken und idealen Einsatzmöglichkeiten.
PgBouncer vs. Pgpool-II: Connection Management entmystifiziert
Bevor wir uns mit den Details von PgBouncer und Pgpool-II befassen, wollen wir ein grundlegendes Verständnis der Kernkonzepte entwickeln, die ihrer Funktionsweise zugrunde liegen.
Terminologie
- Connection Pooling: Die Praxis, bestehende Datenbankverbindungen wiederzuverwenden, anstatt für jede Anfrage eine neue zu öffnen. Dies reduziert den Overhead beim Aufbau und Abbau von Verbindungen und verbessert Leistung und Ressourcenauslastung.
- Proxy: Ein Server, der als Vermittler für Anfragen von Clients fungiert, die Ressourcen von anderen Servern suchen. In unserem Kontext befindet er sich zwischen der Anwendung und der PostgreSQL-Datenbank.
- Load Balancing: Die Verteilung des eingehenden Netzwerkverkehrs auf mehrere Backend-Server, um sicherzustellen, dass kein einzelner Server zu einem Engpass wird. Dies verbessert die Reaktionsfähigkeit und Verfügbarkeit der Anwendung.
- Hohe Verfügbarkeit (HA): Ein Systemdesignansatz, der ein hohes Maß an Betriebskontinuität gewährleistet, oft durch die Eliminierung einzelner Fehlerpunkte und die Bereitstellung von Failover-Mechanismen.
- Read Replicas: Kopien einer Master-Datenbank, die schreibgeschützte Abfragen bedienen können, wodurch die primäre Datenbank entlastet und die Leseskalierbarkeit verbessert wird.
- Statement-Level Pooling: Ein Pooling-Modus, bei dem eine physische Verbindung nach der Ausführung jeder SQL-Anweisung an den Pool zurückgegeben wird. Dies bietet das höchste Potenzial für die Wiederverwendung von Verbindungen, kann jedoch Transaktionen, die mehrere Anweisungen umfassen, ohne sorgfältige Handhabung unterbrechen.
- Transaction-Level Pooling: Ein Pooling-Modus, bei dem eine physische Verbindung nach Abschluss einer Transaktion (
COMMIToderROLLBACK) an den Pool zurückgegeben wird. Dies ist sicherer für Anwendungen, die auf Transaktionsgrenzen angewiesen sind. - Session-Level Pooling: Ein Pooling-Modus, bei dem eine physische Verbindung einem Client zugewiesen wird, bis der Client die Verbindung trennt. Dieses Verhalten ähnelt am ehesten einer direkten Verbindung, bietet aber dennoch Pooling-Vorteile für kurzlebige Clientsitzungen.
PgBouncer: Die schlanke, flotte Connection-Maschine
PgBouncer ist bekannt für seine Einfachheit, Effizienz und seinen Fokus auf Connection Pooling. Es ist ein leichter, Single-Process-, Multi-Thread-Proxy, der dazu entwickelt wurde, eine Sache außergewöhnlich gut zu machen: Verbindungen verwalten.
Prinzipien und Funktionen
PgBouncer arbeitet, indem er eine Reihe von Verbindungen zum PostgreSQL-Backend öffnet und diese dann an eingehende Client-Verbindungen weitergibt. Wenn ein Client die Verbindung trennt, wird die Backend-Verbindung an den Pool zurückgegeben und ist bereit für den nächsten Client. Seine Hauptstärke liegt in seinen verschiedenen Pooling-Modi:
- Session Pooling (Standard): Eine Serververbindung wird der Client-Sitzung für ihre gesamte Dauer zugewiesen. Wenn der Client die Verbindung trennt, wird die Serververbindung an den Pool zurückgegeben. Dies ist der sicherste Modus, da er den Sitzungszustand vollständig erhält.
- Transaction Pooling: Eine Serververbindung wird einem Client nur für die Dauer einer Transaktion zugewiesen. Nach
COMMIToderROLLBACKwird die Verbindung an den Pool zurückgegeben. Dies ermöglicht eine größere Wiederverwendung von Verbindungen, erfordert jedoch, dass Anwendungen sich der Transaktionsgrenzen bewusst sind. Jeder sitzungsbezogene Zustand (wieSET TIMEZONE) wird zwischen den Transaktionen zurückgesetzt. - Statement Pooling: Eine Serververbindung wird einem Client nur für die Dauer einer einzelnen Anweisung zugewiesen. Nach Abschluss der Anweisung wird die Verbindung zurückgegeben. Dies bietet die höchste Wiederverwendung, ist aber am riskantesten, da es Multi-Statement-Transaktionen unterbricht und zu unerwartetem Verhalten führen kann, wenn die Anwendung nicht sorgfältig damit umgeht.
Implementierungs- und Konfigurationsbeispiel
PgBouncer wird über eine einfache INI-ähnliche Datei konfiguriert, typischerweise pgbouncer.ini.
; pgbouncer.ini Beispiel [databases] ; Definieren Sie Ihre Datenbanken. Sie können einen Client-seitigen Datenbanknamen ; einem potenziell anderen Backend-Datenbanknamen und Anmeldeinformationen zuordnen. mydb = host=localhost port=5432 dbname=my_appdb user=webapp_user password=mypwd pool_size=20 [pgbouncer] ; Horchen Sie auf allen Schnittstellen auf Port 6432 listen_addr = * listen_port = 6432 ; Authentifizierungsdatei auth_type = md5 auth_file = users.txt ; Connection Pooling Modus pool_mode = transaction ; Maximale Anzahl erlaubter Client-Verbindungen max_client_conn = 1000 ; Maximale Anzahl von Serververbindungen pro Datenbank (Standard) default_pool_size = 10 ; Minimale Anzahl von Serververbindungen, die im Pool aktiv gehalten werden min_pool_size = 5 ; Wie lange auf die Freigabe einer Verbindung gewartet wird, bevor sie getötet wird server_idle_timeout = 60 ; Wie lange gewartet wird, bis eine Verbindung verfügbar ist query_wait_timeout = 120 ; Log-Level (0=DEBUG, 1=INFO, 2=NOTICE, 3=WARNING, 4=ERROR, 5=FATAL) logfile = /var/log/pgbouncer.log pidfile = /var/run/pgbouncer/pgbouncer.pid
Die Datei users.txt würde username "password_hash" Einträge zur Authentifizierung enthalten.
Um PgBouncer auszuführen:
pgbouncer -d /path/to/pgbouncer.ini
Anwendungen verbinden sich dann mit dem listen_port von PgBouncer (z. B. 6432) anstelle direkt mit PostgreSQL.
Anwendungsszenarien
- Webanwendungen mit hohem Volumen: Ideal für Anwendungen wie Webserver oder Microservices, die häufig Datenbankverbindungen für kurzlebige Anfragen öffnen und schließen.
- Ressourcenbeschränkte Umgebungen: Aufgrund seines minimalen Overheads ist PgBouncer für Container oder kleinere VMs geeignet, bei denen jede Ressource zählt.
- Einfaches Connection Pooling: Wenn die Hauptanforderung die effiziente Wiederverwendung von Verbindungen ist, ohne dass erweiterte Funktionen wie Load Balancing oder hohe Verfügbarkeit benötigt werden.
Pgpool-II: Das funktionsreiche Schweizer Taschenmesser
Pgpool-II ist eine umfassendere Lösung, die nicht nur Connection Pooling, sondern auch Load Balancing, Replikations- und Hochverfügbarkeitsfunktionen bietet. Es wurde als "Middleware" für PostgreSQL entwickelt und bietet eine breite Palette von Funktionalitäten zur Verbesserung von Skalierbarkeit und Zuverlässigkeit.
Prinzipien und Funktionen
Pgpool-II leitet Abfragen an Backend-PostgreSQL-Server weiter und verteilt intelligent Leseabfragen über Replikate, während Schreibabfragen an den Primärserver gesendet werden. Seine Hauptfunktionen umfassen:
- Connection Pooling: Ähnlich wie PgBouncer, wiederverwendet es Verbindungen zu Backend-Servern.
- Load Balancing (Read-Write Splitting): Leitet
SELECT-Anweisungen automatisch an Read Replicas weiter, wodurch die Last auf dem Primärserver reduziert wird, währendINSERT,UPDATE,DELETE-Anweisungen (und andere DDL/DML) an den Primärserver gesendet werden. - Hohe Verfügbarkeit & Automatisches Failover: Überwacht Backend-PostgreSQL-Server und kann im Falle eines Primärausfalls automatisch zu einem Standby-Server wechseln, um den kontinuierlichen Betrieb zu gewährleisten.
- Replikationsmanagement: Kann verschiedene PostgreSQL-Replikationskonfigurationen verwalten (z. B. Streaming-Replikation, logische Replikation).
- Query Caching: Kann Abfrageergebnisse zwischenspeichern, was schreibintensive Workloads weiter beschleunigt (obwohl diese Funktion oft von Caches auf Anwendungsebene oder spezialisierteren Tools gehandhabt wird).
- In-band Administration: Bietet eine Pseudodatenbank für administrative Befehle.
Implementierungs- und Konfigurationsbeispiel
Die Konfiguration von Pgpool-II ist aufgrund seines reichhaltigeren Funktionsumfangs komplexer und wird typischerweise über pgpool.conf verwaltet.
; pgpool.conf Beispiel ; Connection Pooling Einstellungen num_init_children = 32 ; Anzahl der zu startenden Pgpool-II Child-Prozesse max_pool = 4 ; Max. Verbindungen pro Pgpool-II Child zu einem Backend connection_cache = on ; Connection Caching aktivieren ; Backend-Serverdefinitionen backend_hostname0 = '192.168.1.10' backend_port0 = 5432 backend_weight0 = 1 backend_data_directory0 = '/var/lib/postgresql/13/main' backend_flag0 = 'ALLOW_FAILBACK' ; Für Primärserver backend_hostname1 = '192.168.1.11' backend_port1 = 5432 backend_weight1 = 1 backend_data_directory1 = '/var/lib/postgresql/13/main' backend_flag1 = 'ALLOW_FAILBACK' ; Für Standby/Replikat ; Load Balancing Einstellungen load_balance_mode = on ; Read/Write Splitting aktivieren replication_mode = on ; Beim Umgang mit replizierten Backends ; High Availability Einstellungen health_check_period = 5 ; Wie oft die Backend-Gesundheit geprüft wird failover_command = '/etc/pgpool2/failover.sh %d %H %W %P %r' ; Skript, das bei Failover ausgeführt wird failback_command = '/etc/pgpool2/failback.sh %d %H %W %P %r' ; Skript, das bei Failback ausgeführt wird ; Authentifizierungseinstellungen listen_addresses = '*' port = 9999 auth_methods = 'md5' pg_md5 = '/etc/pgpool2/pg_md5' ; Datei für die eigene Benutzerauthentifizierung von Pgpool-II ; Delegierte Authentifizierung an das Backend enable_pool_hba = on pool_hba_file = '/etc/pgpool2/pool_hba.conf' ; Ähnlich wie die pg_hba.conf von PostgreSQL
pg_md5 würde username:password_hash für die Verwaltung von Pgpool-II enthalten. pool_hba.conf regelt den Client-Zugriff auf Pgpool-II.
Um Pgpool-II zu starten:
pgpool -n -d
Anwendungen verbinden sich mit dem port von Pgpool-II (z. B. 9999).
Anwendungsszenarien
- Skalierbarkeit für Leseintensive Workloads: Seine Read-Write-Splitting-Funktionen sind für Anwendungen mit einem hohen Anteil an
SELECT-Abfragen unverzichtbar und verteilen diese effizient über mehrere Replikate. - Automatisierte Hohe Verfügbarkeit: Für geschäftskritische Systeme, die bei einem Ausfall des primären Datenbankservers automatisches Failover und minimale Ausfallzeiten erfordern.
- Vereinfachte Datenbankarchitektur: Wenn Sie einen einzigen Eingangspunkt für Ihre Anwendung zu mehreren PostgreSQL-Servern wünschen, der die Komplexität von Replikation und Failover von der Anwendungsschicht abstrahiert.
- Legacy-Anwendungen: Kann für ältere Anwendungen nützlich sein, die nativ keine Read Replicas oder Failover unterstützen, sodass diese Funktionen extern hinzugefügt werden können.
Auswahl Ihres Proxys
Die Entscheidung zwischen PgBouncer und Pgpool-II hängt weitgehend von Ihren spezifischen Anforderungen und architektonischen Zielen ab:
| Merkmal/Überlegung | PgBouncer | Pgpool-II |
|---|---|---|
| Hauptziel | Effizientes Connection Pooling | Load Balancing, HA, Replikation, Connection Pooling |
| Komplexität | Einfach, leichtgewichtig, einfach zu konfigurieren | Komplexer, funktionsreicher, steilere Lernkurve |
| Ressourcennutzung | Minimal | Höher (wegen zusätzlicher Funktionen) |
| Leistung (Pooling) | Hervorragend, optimiert für schnelle Wiederverwendung von Verbindungen | Gut, aber Overhead für zusätzliche Funktionen vorhanden |
| Load Balancing | Kein natives Load Balancing | Ja, intelligentes Read/Write Splitting |
| Hohe Verfügbarkeit | Keine native HA/Failover | Ja, automatisiertes Failover und Gesundheitsprüfungen |
| Read Replicas | Kann Verbindungen zu einem einzelnen Replikat poolen, aber kein intelligentes Routing oder Load Balancing über mehrere hinweg. | Ja, verteilt Leseanfragen über Replikate. |
| Replikationsmanagement | Nein | Ja, verwaltet verschiedene Replikationskonfigurationen |
| Query Caching | Nein | Ja (kann Ergebnisse zwischenspeichern) |
| Best Use Case | Anwendungen, die reine Connection Multiplexing zu einer einzigen Datenbankinstanz (Primär- oder Replikatinstanz) benötigen. | Anwendungen, die Load Balancing, HA und die Abstraktion von Replikation von der Anwendungsschicht benötigen. |
Verwenden Sie PgBouncer, wenn:
- Ihr Hauptanliegen einfach die Reduzierung des Verbindungs-Overheads ist.
- Ihre Anwendung bereits Read-Write-Splitting handhabt oder Sie sich nur mit einer Primärdatenbank verbinden.
- Sie eine minimalistische Lösung mit minimalem Overhead suchen.
- Sie HA auf einer anderen Ebene verwalten (z. B. Dienste von Cloud-Anbietern, Patroni).
Verwenden Sie Pgpool-II, wenn:
- Sie Leseabfragen über mehrere Replikate verteilen müssen, um Lesevorgänge zu skalieren.
- Sie automatische Failover-Funktionen benötigen, um hohe Verfügbarkeit zu gewährleisten.
- Sie die Datenbankinteraktion Ihrer Anwendung vereinfachen möchten, indem Sie Replikationsdetails abstrahieren.
- Sie einen einzigen Eintrittspunkt für Ihre Anwendung zu einem Cluster von PostgreSQL-Servern benötigen.
Es ist auch erwähnenswert, dass Sie in einigen fortgeschrittenen Setups PgBouncer auf Pgpool-II anwenden oder es zusammen mit anderen HA-Lösungen wie Patroni verwenden könnten. So kann beispielsweise PgBouncer vor einem Patroni-Cluster (der HA und Failover handhabt) platziert werden, um Connection Pooling bereitzustellen, ohne die HA-Funktionen von Pgpool-II zu benötigen.
Fazit: Passen Sie Ihr PostgreSQL-Frontend an
Die Wahl zwischen PgBouncer und Pgpool-II hängt von einer sorgfältigen Bewertung der spezifischen Anforderungen Ihrer Anwendung an Skalierbarkeit, Verfügbarkeit und Komplexität ab. PgBouncer bietet elegantes, hochperformantes Connection Pooling mit minimalem Ressourcenverbrauch und ist damit ideal für reine Multiplexing-Aufgaben. Pgpool-II hingegen bietet eine robuste, funktionsreiche Middleware für fortschrittliches Load Balancing, Hohe Verfügbarkeit und Replikationsmanagement und abstrahiert beträchtliche Komplexität von der Anwendung. Beide sind leistungsstarke Werkzeuge, aber die richtige Wahl stellt sicher, dass Ihre PostgreSQL-Infrastruktur nicht nur optimal funktioniert, sondern auch anmutig mit zukünftigen Anforderungen skaliert.

