Vor langer Zeit, in einer weit entfernten Galaxie, waren „Threads“ eine Programmierneuheit, die selten verwendet wurde und der man selten vertraute. In dieser Umgebung entschieden die ersten PostgreSQL-Entwickler, dass die Forkung eines Prozesses für jede Verbindung zur Datenbank die sicherste Wahl ist. Es wäre doch schade, wenn Ihre Datenbank abstürzt.
Seitdem ist viel Wasser unter diese Brücke geflossen, aber die PostgreSQL-Community hat an ihrer ursprünglichen Entscheidung festgehalten. Es ist schwierig, ihre Argumentation zu bemängeln – denn es ist absolut wahr, dass:
- Jeder Client mit seinem eigenen Prozess verhindert, dass ein sich schlecht verhaltender Client die gesamte Datenbank zum Absturz bringt.
- Auf modernen Linux-Systemen ist der Unterschied im Overhead zwischen dem Forken eines Prozesses und dem Erstellen eines Threads viel geringer als früher.
- Die Umstellung auf eine Multithread-Architektur erfordert umfangreiche Umschreibungen.
In modernen Webanwendungen neigen Clients jedoch dazu, viele Verbindungen zu öffnen. Entwicklern wird oft dringend davon abgeraten, eine Datenbankverbindung aufrechtzuerhalten, während andere Vorgänge stattfinden. „Öffne eine Verbindung so spät wie möglich, schließe eine Verbindung so schnell wie möglich“. Aber das verursacht ein Problem mit der Architektur von PostgreSQL – das Verzweigen eines Prozesses wird teuer, wenn Transaktionen sehr kurz sind, wie es die allgemeine Meinung vorschreibt.
Die Verbindungspool-Architektur
Die Verwendung einer modernen Sprachbibliothek reduziert das Problem etwas – Verbindungspooling ist ein wesentliches Merkmal der meisten populären Bibliotheken mit Datenbankzugriff. Es stellt sicher, dass „geschlossene“ Verbindungen nicht wirklich geschlossen werden, sondern an einen Pool zurückgegeben werden, und das „Öffnen“ einer neuen Verbindung gibt dieselbe „physikalische Verbindung“ zurück, wodurch die tatsächliche Verzweigung auf der PostgreSQL-Seite reduziert wird.
Moderne Webanwendungen jedoch sind selten monolithisch und verwenden oft mehrere Sprachen und Technologien. Die Verwendung eines Verbindungspools in jedem Modul ist kaum effizient:
- Selbst mit einer relativ kleinen Anzahl von Modulen und einer kleinen Poolgröße in jedem erhalten Sie viele Serverprozesse. Der Kontextwechsel zwischen ihnen ist kostspielig.
- Die Pooling-Unterstützung variiert stark zwischen Bibliotheken und Sprachen – ein Pool, der sich schlecht verhält, kann alle Ressourcen verbrauchen und die Datenbank für andere Module unzugänglich machen.
- Es gibt keine zentrale Kontrolle – Sie können keine Maßnahmen wie kundenspezifische Zugriffsbeschränkungen verwenden.
Infolgedessen wurden beliebte Middlewares für PostgreSQL entwickelt. Diese befinden sich zwischen der Datenbank und den Clients, manchmal auf einem separaten Server (physisch oder virtuell) und manchmal auf derselben Box, und erstellen einen Pool, mit dem sich Clients verbinden können. Diese Middleware sind:
- Optimiert für PostgreSQL und seine ziemlich einzigartige Architektur unter modernen DBMS.
- Stellen Sie eine zentralisierte Zugriffskontrolle für verschiedene Clients bereit.
- Ermöglichen es Ihnen, die gleichen Belohnungen wie clientseitige Pools zu ernten, und noch mehr (wir werden diese in unseren nächsten Posts ausführlicher besprechen)!
Nachteile von PostgreSQL Connection Pooler
Ein Verbindungspooler ist ein nahezu unverzichtbarer Bestandteil eines produktionsbereiten PostgreSQL-Setups. Obwohl es viele gut dokumentierte Vorteile bei der Verwendung eines Verbindungspoolers gibt, gibt es sie Einige Argumente, die dagegen sprechen:
- Die Einführung einer Middleware in die Kommunikation führt unweigerlich zu einer gewissen Latenz. Wenn es sich jedoch auf demselben Host befindet und den Overhead für das Forking einer Verbindung berücksichtigt, ist dies in der Praxis vernachlässigbar, wie wir im nächsten Abschnitt sehen werden.
- Eine Middleware wird zu einem Single Point of Failure. Die Verwendung eines Clusters auf dieser Ebene kann dieses Problem lösen, aber das führt zu zusätzlicher Komplexität in der Architektur.
- Eine Middleware verursacht zusätzliche Kosten. Sie benötigen entweder einen zusätzlichen Server (oder 3) oder Ihre Datenbankserver müssen über genügend Ressourcen verfügen, um zusätzlich zu PostgreSQL einen Verbindungspooler zu unterstützen.
- Das Teilen von Verbindungen zwischen verschiedenen Modulen kann zu einer Sicherheitslücke werden. Es ist sehr wichtig, dass wir pgPool oder PgBouncer so konfigurieren, dass Verbindungen bereinigt werden, bevor sie an den Pool zurückgegeben werden.
- Die Authentifizierung verlagert sich vom DBMS zum Connection Pooler. Dies ist möglicherweise nicht immer akzeptabel.
- Es erhöht die Angriffsfläche, es sei denn, der Zugriff auf die zugrunde liegende Datenbank wird gesperrt, um den Zugriff nur über den Connection Pooler zu ermöglichen.
- Es erstellt eine weitere Komponente, die gewartet, auf Ihre Arbeitslast abgestimmt, häufig mit Sicherheitspatches versehen und bei Bedarf aktualisiert werden muss.
Sollten Sie einen PostgreSQL Connection Pooler verwenden?
Jedoch werden all diese Probleme in der PostgreSQL-Community ausführlich diskutiert, und Minderungsstrategien stellen sicher, dass die Vorteile eines Verbindungspoolers ihre Nachteile bei weitem übersteigen. Unsere Tests zeigen, dass selbst eine kleine Anzahl von Clients erheblich von der Verwendung eines Verbindungspoolers profitieren kann. Sie sind den zusätzlichen Konfigurations- und Wartungsaufwand wert.
Im nächsten Beitrag werden wir einen der beliebtesten Verbindungspooler in der PostgreSQL-Welt besprechen – PgBouncer, gefolgt von Pgpool-II und schließlich einen Leistungstestvergleich dieser beiden PostgreSQL-Verbindungspooler in unserem letzten Beitrag der Serie.
PostgreSQL Connection Pooling-Reihe
|
---|