Was verwaltetes Postgres für Laravel ändert
Serverless-Postgres ist für Lasten mit einer Verbindung je Anfrage geformt. Laravel hält langlebige Verbindungen in seinen Queue-Workern, und dort liegen die Überraschungen.
Verwaltetes Postgres hieß früher: ein Server, den jemand anders patcht. Zunehmend heißt es Plattform - Speicher getrennt von Compute, Verbindungen über einen Pooler vermittelt, Datenbanken, die sich wie Git verzweigen, und Compute, das suspendiert, wenn niemand fragt.
All das ist für eine Last gebaut, bei der eine Anfrage eintrifft, eine Abfrage ausführt und verschwindet. Laravel ist genau diese Last auf der Web-Schicht und überall sonst das Gegenteil.
Die Diskrepanz, klar benannt
Eine Laravel-Anwendung hat drei Arten von Datenbank-Client, und sie verhalten sich völlig unterschiedlich:
Web-Anfragen. PHP-FPM, Verbindung auf und zu je Anfrage. Das passt exakt zum Serverless-Modell.
Queue-Worker. queue:work verbindet beim Start und hält diese Verbindung
sein ganzes Leben, ob er gerade etwas verarbeitet oder nicht. Zwanzig Worker
sind zwanzig dauerhafte Verbindungen, bevor ein einziger Besucher eintrifft.
Der Scheduler. Ein Cron-Eintrag, der schedule:run jede Minute ausführt,
für immer.
Anbieter bepreisen und dimensionieren um den ersten Fall. Der zweite füllt ein
Verbindungskontingent und ist die häufigste Ursache eines
SQLSTATE[HY000] [1040] Too many connections - ein Fehler, den wir auf unseren
englischsprachigen Fehlerseiten im Einzelnen aufschlüsseln. Der dritte hebelt
Scale-to-Zero still aus.
Scale-to-Zero und der Scheduler
Das bekommen die meisten zuerst falsch, und es ist Arithmetik, keine Meinung.
Compute suspendiert nach einer Leerlaufzeit. schedule:run setzt jede Minute
eine Abfrage ab. Ist die Leerlaufschwelle länger als eine Minute, suspendiert
die Datenbank nie, und Sie zahlen für dauerhaft laufendes Compute mit
Kaltstart-Eigenschaften obendrauf.
Es gibt drei ehrliche Antworten. Akzeptieren und für Dauerbetrieb dimensionieren - dann ist eine konventionelle Instanz womöglich günstiger. Den Scheduler auf etwas verlagern, das die Datenbank nicht anfasst, wenn nichts ansteht - was heißt, dass der Zeitplan ohne Abfrage lesbar sein muss. Oder Kaltstarts in einer Testumgebung akzeptieren und in Produktion nicht, wo Scale-to-Zero sich wirklich auszahlt.
Niemand sollte das von einer Rechnung erfahren.
Pooling-Modi, und damit das, was bricht
Jedes Serverless-Postgres setzt einen Pooler davor. Der Modus entscheidet, was Ihre Anwendung darf.
Session Pooling gibt Ihnen eine echte Backend-Verbindung für die Dauer Ihrer Verbindung. Alles funktioniert. Sie bekommen auch weit weniger effektive Verbindungen, was meist der Grund war, warum Sie kamen.
Transaction Pooling gibt Ihnen ein Backend nur für die Dauer einer Transaktion. Das liefert Tausende Client-Verbindungen über wenige echte und entfernt alles, was über Anweisungen hinweg reicht:
- Serverseitig vorbereitete Statements, die PDO standardmäßig nutzt. Das trifft Laravel speziell, und die Behebung ist ein Flag in der Verbindungszeichenkette oder eine Emulationseinstellung statt einer Codeänderung - sie muss aber bewusst gesetzt werden.
- Advisory Locks, also können
withoutOverlapping()an einem Zeitplan undShouldBeUniquean einem Job sich anders verhalten als geschrieben, wenn sie über die Datenbank laufen. SET-Anweisungen, sodass alles, was je Verbindung eine Zeitzone oder einen Suchpfad setzt, nicht mehr hält.LISTEN/NOTIFYund jeder langlebige Cursor.
Die praktische Anordnung sind zwei Verbindungen in config/database.php: der
gepoolte Endpunkt für Web-Anfragen, der direkte für Migrationen, Queue-Worker
und alles, was eine Sperre hält. Das sind zehn Zeilen und sie verhindern den
größten Teil dieses Artikels.
Branching, die wirklich neue Fähigkeit
Ein Branch ist eine Copy-on-Write-Datenbank in Produktionsgröße, in Sekunden erzeugt. Für Laravel landet das auf einem konkreten Problem: Migrationen, die gegen vierzig Zeilen sicher sind und gegen vier Millionen vier Minuten sperren.
Ein Branch je Pull Request, Migrationen im CI dagegen ausgeführt, die Dauer protokolliert. Jetzt scheitert eine gefährliche Schemaänderung an einem Build statt an einem Deployment. Das ist das stärkste Argument für eine Plattform gegenüber einer Instanz, und es wiegt mehr als das Preismodell.
Zwischen ihnen wählen
Eine konventionelle verwaltete Instanz - RDS, Cloud SQL, das schlichte Postgres eines Anbieters - wenn die Anwendung eine stetige Worker-Flotte hat, wenn Sie vorhersehbare Verbindungszahlen wollen, und wenn der Betriebsaufwand, den Sie wegkaufen, das Patchen ist und nicht das Skalieren. Für die meisten Geschäftsanwendungen ist das weiterhin richtig, und es ist unmodisch, das zu sagen.
Serverless-Postgres mit Branching, wenn Ihnen die Migrationsprüfung wichtig ist, wenn Umgebungen zahlreich und kurzlebig sind, oder wenn der Verkehr wirklich stoßweise kommt. Planen Sie die Pooling-Arbeit ein, statt sie für eine Änderung an der Verbindungszeichenkette zu halten.
Eine Plattform mit Auth und Storage daran, wenn Sie diese ebenfalls nutzen. Nutzen Sie sie nur als Datenbank, wählen Sie einen Postgres-Anbieter und sollten ihn als solchen vergleichen.
Alles MySQL-Kompatible, aber Geshardete nur mit zuvor gelesener
Einschränkungsliste. Referenzielle Integrität, Transaktionen über Shards hinweg
und ORDER BY über eine geshardete Tabelle sind die Stellen, an denen das
Modell durchscheint, und Laravel-Migrationen schreiben bereitwillig DDL, das
die Plattform annimmt und nicht durchsetzt.
Die Prüfung, die einen Nachmittag kostet
Bevor Sie sich festlegen, führen Sie das Echte aus: eine Migration mit Indexaufbau auf einer produktionsgroßen Tabelle, Ihre tatsächliche Worker-Zahl gleichzeitig verbunden, und einen geplanten Befehl, der eine Sperre hält. Drei Messungen, ein Nachmittag.
Jedes Problem in diesem Artikel ist so günstig zu finden und im zweiten Monat teuer.
