Warum brauchen wir Nachrichtenbroker wie RabbitMQ über eine Datenbank wie PostgreSQL?

214

Ich bin neu bei Nachrichtenbrokern wie RabbitMQ, mit denen wir Aufgaben / Nachrichtenwarteschlangen für ein Planungssystem wie Celery erstellen können .

Hier ist die Frage:

  • Ich kann in PostgreSQL eine Tabelle erstellen, die an neue Aufgaben angehängt und vom Verbraucherprogramm wie Celery verwendet werden kann.

  • Warum um alles in der Welt sollte ich dafür eine ganz neue Technologie wie RabbitMQ einrichten wollen?

Ich glaube, Skalierung kann nicht die Antwort sein, da unsere Datenbank wie PostgreSQL in einer verteilten Umgebung funktionieren kann.

Ich habe gegoogelt, welche Probleme die Datenbank für das jeweilige Problem aufwirft, und festgestellt:

  • Durch das Abrufen ist die Datenbank beschäftigt und weist eine geringe Leistung auf
  • Sperren des Tisches -> wieder leistungsschwache
  • Millionen von Aufgabenreihen -> Auch hier ist die Abfrage von geringer Leistung

Wie löst RabbitMQ oder ein anderer solcher Nachrichtenbroker diese Probleme?

Außerdem habe ich herausgefunden, dass das AMQPProtokoll das ist, was es folgt. Was ist daran großartig?

Kann Redis auch als Nachrichtenbroker verwendet werden? Ich finde es analog zu Memcached als RabbitMQ.

Bitte werfen Sie etwas Licht darauf!

Yugal Jindle
quelle
9
Die Auswirkungen des Sperren sollten bei PostgreSQL viel geringer sein, da es MVCC implementiert, bei dem Leser nicht von Autoren blockiert werden und umgekehrt. Die meisten Artikel, in denen ich die Verwendung von Datenbanken als Nachrichtenwarteschlangen kritisiert habe, haben MySQL im Sinn.
CadentOrange
Ein Nachrichtenbroker verschiebt Daten zwischen Knoten, während eine Datenbank Daten an einem Ort aufbewahrt. Die Tatsache, dass Sie von mehreren Knoten aus auf Daten in einer Datenbank zugreifen können, macht es auf den ersten Blick nicht zu einem guten Werkzeug, um Daten schnell zwischen Knoten zu übertragen.
theMayer
2
"Scheduling System like celery" - Ich habe gerade aus der Frage etwas gelernt, das für mein Design nützlich sein wird . Nun, um die Antworten zu lesen ...
Mark K Cowan
Mit Message Broker werden Produzent und Konsument entkoppelt.
Giorgi Dvalishvili
Sie können den folgenden Link anzeigen. Es hat eine breite Beschreibung: stackoverflow.com/a/51377756/3073945
Md. Sajedul Karim

Antworten:

110

Die Warteschlangen von Rabbit befinden sich im Speicher und sind daher viel schneller als die Implementierung in einer Datenbank. Eine (gute) dedizierte Nachrichtenwarteschlange sollte auch wesentliche Funktionen in Bezug auf die Warteschlange bieten, wie z. B. Drosselung / Flusskontrolle und die Möglichkeit, verschiedene Routing-Algorithmen auszuwählen, um ein Paar zu nennen (Kaninchen bietet diese und mehr). Abhängig von der Größe Ihres Projekts möchten Sie möglicherweise auch, dass die Nachrichtenkomponente von Ihrer Datenbank getrennt wird, damit eine Komponente, die stark ausgelastet ist, den Betrieb der anderen nicht behindert.

Was die von Ihnen erwähnten Probleme betrifft:

  • Abfrage der Datenbank buzy und mit geringer Leistung zu halten : Mit RabbitMQ, Hersteller können Push - Updates für die Verbraucher , die weit mehr performant als Polling ist. Daten werden einfach an den Verbraucher gesendet, wenn dies erforderlich ist, sodass keine verschwenderischen Überprüfungen erforderlich sind.

  • Sperren der Tabelle -> wieder leistungsschwache: Es ist keine Tabelle zu sperren: P.

  • Millionen von Aufgabenzeilen -> Wiederum ist die Abfrage von geringer Leistung: Wie oben erwähnt, arbeitet Rabbitmq schneller, da es sich im RAM befindet, und bietet Flusskontrolle. Bei Bedarf kann die Festplatte auch zum vorübergehenden Speichern von Nachrichten verwendet werden, wenn der Arbeitsspeicher knapp wird. Nach 2.0 hat Rabbit seine RAM-Nutzung erheblich verbessert. Clustering-Optionen sind ebenfalls verfügbar.

In Bezug auf AMQP würde ich sagen, dass ein wirklich cooles Feature der "Austausch" ist und die Fähigkeit, zu anderen Börsen zu gelangen. Dies gibt Ihnen mehr Flexibilität und ermöglicht es Ihnen, eine Vielzahl von ausgefeilten Routing-Typologien zu erstellen, die beim Skalieren sehr nützlich sein können. Ein gutes Beispiel finden Sie unter:


(Quelle: springsource.com )

und: http://blog.springsource.org/2011/04/01/routing-topologies-for-performance-and-scalability-with-rabbitmq/

In Bezug auf Redis kann es schließlich als Nachrichtenbroker verwendet werden und ist gut geeignet. Rabbitmq bietet jedoch mehr Funktionen für die Nachrichtenwarteschlange als Redis, da Rabbitmq von Grund auf als dedizierte Nachrichtenwarteschlange auf Unternehmensebene mit vollem Funktionsumfang entwickelt wurde. Redis hingegen wurde in erster Linie als speicherinterner Schlüsselwertspeicher entwickelt (obwohl es jetzt viel mehr als das tut; es wird sogar als Schweizer Taschenmesser bezeichnet). Trotzdem habe ich viele Leute gelesen / gehört, die mit Redis gute Ergebnisse für kleinere Projekte erzielt haben, aber in größeren Anwendungen nicht viel darüber gehört.

Hier ist ein Beispiel für die Verwendung von Redis in einer Chat-Implementierung mit langen Umfragen: http://eflorenzano.com/blog/2011/02/16/technology-behind-convore/

Jaigus
quelle
2
Ich habe eine JMS-Implementierung (dh ein Message-Passing-System) über einer Datenbank implementiert. Ich kann Ihnen sagen , dass es ist möglich, aber es ist nicht lustig und es nicht in der Regel auszahlen , es zu tun. Einige der von Ihnen erwähnten Probleme können umgangen werden, erhöhen jedoch die Komplexität erheblich. Alles in allem stimme ich zu: Verwenden Sie ein dediziertes MQ-System, falls Sie eines benötigen. Bei geringer Arbeitsbelastung können Sie jedoch davonkommen, es in der Datenbank zu haben.
Joachim Sauer
1
Sie haben einfach alle Bedenken / Zweifel abgedeckt. Super Antwort!
Yugal Jindle
Das ist interessant. Was ist übrigens mit Konsistenz? Was ist, wenn sich Hunderte von Jobs in einer Warteschlange befinden und der Knoten, der sie in RAM hält, abstürzt?
Mahn
22
Tatsächlich gibt es bei PostgreSQL weder Abfragen (siehe NOTIFY) noch Tabellensperren (siehe MVCC). Obwohl PostgreSQL immer noch nicht für das Einreihen von Nachrichten ausgelegt ist, ist es nicht völlig ungeeignet.
JKJ
3
Wie @jkj gesagt hat, gibt es NOTIFY und keine Tabellensperren. Das einzige Problem scheint die hohe Bandbreite der Nachrichten zu sein. Könnten Sie nicht eine dedizierte PostgreSQL-Instanz haben, anstatt ein völlig neues System wie Rabbit zu warten? Sie können 1) eine einzelne PostgreSQL-Instanz verwenden, bis Sie einen Engpass erreichen, dann 2) ein dediziertes Postgres verwenden und schließlich 3) einfach zu Rabbit als Broker wechseln. Es scheint, als würde der Start mit Rabbit voroptimiert.
Joe
71

PostgreSQL 9.5

PostgreSQL 9.5 enthält SELECT ... FOR UPDATE ... SKIP LOCKED. Dies macht die Implementierung funktionierender Warteschlangensysteme viel einfacher und einfacher. Möglicherweise benötigen Sie kein externes Warteschlangensystem mehr, da es jetzt einfach ist, 'n' Zeilen abzurufen, die von keiner anderen Sitzung gesperrt wurden, und sie gesperrt zu halten, bis Sie die Bestätigung bestätigen, dass die Arbeit erledigt ist. Es funktioniert sogar mit zweiphasigen Transaktionen, wenn eine externe Koordination erforderlich ist.

Externe Warteschlangensysteme bleiben nützlich und bieten vordefinierte Funktionen, bewährte Leistung, Integration in andere Systeme, Optionen für horizontale Skalierung und Verbund usw. In einfachen Fällen benötigen Sie sie jedoch nicht mehr wirklich.

ältere Versionen

Sie brauchen solche Werkzeuge nicht, aber die Verwendung eines kann das Leben erleichtern. Das Ausführen von Warteschlangen in der Datenbank sieht einfach aus, aber Sie werden in der Praxis feststellen, dass es in einer relationalen Datenbank sehr schwierig ist , eine leistungsstarke, zuverlässige gleichzeitige Warteschlange zu erstellen.

Deshalb gibt es Tools wie PGQ .

Sie können das Abrufen in PostgreSQL mit LISTENund loswerden NOTIFY, aber das löst nicht das Problem, Einträge am oberen Rand der Warteschlange zuverlässig an genau einen Verbraucher zu verteilen, während gleichzeitig ein sehr gleichzeitiger Vorgang erhalten bleibt und Einfügungen nicht blockiert werden. All die einfachen und offensichtlichen Lösungen, von denen Sie glauben, dass sie dieses Problem in der realen Welt nicht lösen, degenerieren tendenziell zu weniger effizienten Versionen des Abrufs von Warteschlangen für einzelne Mitarbeiter.

Wenn Sie keine gleichzeitig abrufenden Warteschlangen für mehrere Worker benötigen, ist die Verwendung einer einzelnen Warteschlangentabelle in PostgreSQL durchaus sinnvoll.

Craig Ringer
quelle
11
Die Zeile reliably handing out entries off the top of the queue to exactly one consumer while preserving highly concurrent operation and not blocking inserts. fasst es zusammen - Richtig?
Yugal Jindle