23 Punkte von xguru 2023-04-13 | 6 Kommentare | Auf WhatsApp teilen
  • RabbitMQ entfernt und durch eine Queue in PostgresDB auf Basis von SQL ersetzt
  • Der Austausch dauerte etwa einen halben Tag, und der Sourcecode wurde um 580 Zeilen reduziert
  • Viel wichtiger ist, dass Zuverlässigkeit und Resilienz deutlich verbessert wurden
  • Es geht nicht um Probleme von Queue-Systemen wie RabbitMQ, sondern schlicht um den Versuch, die Wartung zu vereinfachen
    • Prequel, das diesen Artikel verfasst hat, ist ein Produkt, das B2B-SaaS-Unternehmen mit groß angelegten Datenpipelines dabei hilft, sich mit den Datenbanken ihrer Kunden zu synchronisieren
  • Die Architektur bestand aus RabbitMQ + AQMP + Helm + einem GoLang-Wrapper; das funktionierte eine Zeit lang gut, aber dann traten Probleme auf
    • Die Zustellung von Nachrichten verzögerte sich so stark, dass Nachrichten abgebrochen wurden
    • Durch Prefetching auf Consumer-Seite wurden bereits die nächsten Nachrichten reserviert, während die aktuelle noch nicht abgeschlossen war
    • Wenn man diesen Prefetch auf 0 setzt, bedeutet das unendlich, daher lässt sich Prefetching nicht deaktivieren
    • Das Problem entstand, weil die Verarbeitung empfangener Nachrichten meist lang laufende Aufgaben sind (Datenübertragungen)
  • Man verstand zwar genau, was passiert war, hatte aber keine Möglichkeit, es sofort zu beheben. Da Produktionskunden betroffen waren, konnte man nicht einfach abwarten
  • Deshalb wurde auf eine einfache Lese-/Schreibweise mit genau einer Tabelle in Postgres umgestellt
    • Durch Read-/Write-Row-Level-Locks wird sichergestellt, dass jeweils nur ein Consumer eine Aufgabe liest
    • Lächerlich einfach, aber es funktioniert perfekt
  • Ein weiterer Vorteil ist, dass der Anwendungszustand nicht mehr zwischen RabbitMQ und Postgres aufgeteilt ist, sondern in einem System zusammengeführt wurde

6 Kommentare

 
galadbran 2023-04-15

Ich habe in mysql ebenfalls selbst eine Queue mit Row-Level-Locks implementiert, und sie läuft seit Jahren stabil im Produkt.
Ich wollte schlicht mehreren Workern eine queue-ähnliche Funktion bereitstellen und dabei das Payload zusammen mit Zuständen innerhalb der Queue wie wartend/in Bearbeitung/fehlgeschlagen (bei Abschluss gelöscht) speichern.

Wenn man im Haupttext sieht, dass in kurzer Zeit von RabbitMQ auf die Datenbank umgestellt wurde, denke ich, dass man die allgemeine Einsetzbarkeit sowie die vielfältigen Funktionen und Konfigurationsmöglichkeiten eines separaten spezialisierten Queue-Service schlicht nicht brauchte.

 
pseudojo 2023-04-15

Offenbar sind Probleme entstanden, weil sich das manuelle Senden des ACKs und die DB-Transaktion gegenseitig in die Quere kamen,
interessant ist, dass man das nicht durch Engineering gelöst hat, sondern indem man RabbitMQ entfernt hat.
Dabei trifft RabbitMQ wohl keine Schuld ...

 
laracool 2023-04-13

https://news.ycombinator.com/item?id=35526846
In den Kommentaren gibt es viele Meinungen.

 
dddddd 2023-04-13

Es scheint auch so etwas zu geben, das auf ähnliche Weise funktioniert: https://github.com/pjongy/jasyncq

 
laracool 2023-04-13

Es scheint, als könnte es passieren, dass dieselben Datensätze gleichzeitig per select ausgewählt werden. Mich würde interessieren, wie das gelöst wurde.

 
dddddd 2023-04-13

Dort steht wohl row level lock.