Tools
PgBouncer auf 4x Durchsatz skalieren
ClickHouse hat eine detaillierte Analyse veroeffentlicht, wie PgBouncer von einem single-threaded Prozess zu einem verteilten Fleet skaliert werden kann - mit beeindruckenden Ergebnissen: 336.000 Transaktionen pro Sekunde statt 77.000 bei 256 Clients.
Das Problem
PgBouncer ist single-threaded - ein Prozess nutzt nur einen CPU-Core. Auf einer 16-vCPU-Machine sitzen 15 Cores im Leerlauf, waehrend der Pooler zum Flaschenhals wird.
Die Loesung: SO_REUSEPORT und Peering
Die Loesung ist elegant:
- Fleet von Prozessen - Multiple PgBouncer-Prozesse proportional zu den verfuegbaren Cores
- SO_REUSEPORT - Alle Prozesse binden denselben Port, der Kernel verteilt die Connections
- Peering - Prozesse sind sich ihrer Nachbarn bewusst und koennen Query-Cancellations weiterleiten
Das Problem mit Query-Cancellations: Eine Cancel-Anfrage kommt auf einer neuen Connection mit einem Cancel-Key. Ohne Peering landet sie beim falschen Prozess. Mit Peering wird die Cancel-Anfrage an den Prozess weitergeleitet, der die Session besitzt.
Benchmarks
| Clients | Single TPS | Single CPU | Fleet TPS | Fleet CPU |
|---|---|---|---|---|
| 8 | 8,910 | 0.8% | 6,450 | 2.9% |
| 32 | 54,203 | 5.2% | 64,244 | 12.3% |
| 64 | 86,570 | 8.3% | 219,439 | 31.9% |
| 128 | 83,463 | 8.1% | 320,547 | 45.9% |
| 256 | 76,893 | 7.7% | 336,469 | 48.9% |
Bei geringer Last ist der Single-Prozess sogar etwas schneller (keine Parallelisierung noetig). Aber unter echter Concurrency zeigt die Fleet ihre Staerke: 4x Durchsatz bei voller CPU-Auslastung.
Connection Budget
max_client_conn und max_db_connections werden auf die Prozesse aufgeteilt. So wird das Connection-Budget nie ueberschritten, selbst bei mehreren Prozessen.
ClickHouse Managed Postgres nutzt diese Konfiguration standardmaessig. Fuer eigene Deployments: Die Doku zeigt, wie man PgBouncer mit SO_REUSEPORT und Peering aufsetzt.
Link: Original Artikel