2014-11-24 11 views
7

Kann jemand bitte erklären, was hinter den Kulissen in einem RabbitMQ-Cluster mit mehreren Knoten und Warteschlangen gespiegelt passiert, wenn es auf einem Slave-Knoten veröffentlicht?RabbitMQ Clustering und Mirror Queues Verhalten hinter den Kulissen

Von dem, was ich lese, scheint es, dass alle anderen Aktionen als veröffentlicht nur auf den Master und der Master überträgt dann die Wirkung der Aktionen auf die Slaves (das ist aus der Dokumentation). Bilden Sie mein Verständnis es bedeutet, dass ein Verbraucher immer Nachricht aus der Master-Warteschlange konsumieren wird. Wenn ich außerdem eine Anfrage an einen Slave zum Verbrauch einer Nachricht sende, führt dieser Slave einen zusätzlichen Sprung aus, indem er zum Master gelangt, um diese Nachricht zu holen.

Aber was passiert, wenn ich auf einem Slave-Knoten veröffentlichen? Wird dieser Knoten das gleiche tun, um zuerst die Nachricht an den Master zu senden?

Es scheint so, als ob es so viele Extra-Hops im Umgang mit Sklaven gibt, also scheint es, dass Sie eine bessere Leistung haben könnten, wenn Sie nur den Master kennen. Aber wie gehen Sie mit Master-Fehlern um? Dann wird einer der Slaves zum Master gewählt, also müssen Sie wissen, wo Sie sich anmelden müssen?

Wir bitten um all dies, weil wir RabbitMQ Cluster mit HAProxy im Vordergrund verwenden, so dass wir die Clusterstruktur von unseren Apps entkoppeln können. Auf diese Weise wird der HAProxy immer dann auf lebende Knoten umgeleitet, wenn ein Knoten fertig ist. Aber wir haben Probleme, wenn wir einen der Kaninchenknoten töten. Die Verbindung zum Hasen ist permanent, wenn sie fehlschlägt, musst du sie neu erstellen. Außerdem müssen Sie die Nachrichten in diesen Fällen erneut senden, sonst werden Sie sie verlieren.

Sogar mit all dem können Nachrichten immer noch verloren gehen, weil sie möglicherweise auf der Durchreise sind, wenn ich einen Knoten (in einigen Puffern, irgendwo im Netzwerk usw.) kill. Sie müssen also Transaktionen oder Publisher-Bestätigungen verwenden, die die Zustellung garantieren, nachdem alle Spiegel mit der Nachricht gefüllt wurden. Aber hier noch ein Problem. Möglicherweise haben Sie doppelte Nachrichten, da der Broker möglicherweise eine Bestätigung gesendet hat, die den Hersteller nie erreicht hat (aufgrund von Netzwerkfehlern usw.). Daher müssen Consumer-Anwendungen Deduplizierung durchführen oder eingehende Nachrichten in einer idempotenten Weise verarbeiten.

Gibt es eine Möglichkeit, dies zu vermeiden? Oder muss ich entscheiden, ob ich einige Nachrichten verlieren kann, anstatt einige Nachrichten zu duplizieren?

Antwort

14

Kann jemand bitte erklären, was hinter den Kulissen in einem RabbitMQ-Cluster mit mehreren Knoten und Warteschlangen gespiegelt passiert, wenn es auf einem Slave-Knoten veröffentlicht wird?

This blog umreißt genau was passiert.

Aber was passiert, wenn ich auf einem Slave-Knoten veröffentlichen? Wird dieser Knoten das gleiche tun, um zuerst die Nachricht an den Master zu senden?

Die Nachricht wird an die Hauptwarteschlange umgeleitet, dh an den Knoten, auf dem die Warteschlange erstellt wurde.

Aber wie behandeln Sie Masterfehler? Dann wird einer der Slaves zum Master gewählt, also müssen Sie wissen, wo Sie sich anmelden müssen?

Auch dies ist abgedeckt here. Im Wesentlichen benötigen Sie einen separaten Dienst, der RabbitMQ abfragt und feststellt, ob Knoten aktiv sind oder nicht. RabbitMQ stellt hierfür eine management API zur Verfügung.Ihre veröffentlichenden und konsumierenden Anwendungen müssen entweder direkt oder über einen gemeinsamen Datenspeicher auf diesen Dienst zugreifen, um festzustellen, ob der richtige Knoten veröffentlicht oder verwendet wird.

Die Verbindung zu Hase ist permanent, wenn sie fehlschlägt, müssen Sie sie neu erstellen. Außerdem müssen Sie die Nachrichten in diesen Fällen erneut senden, sonst werden Sie sie verlieren.

Sie müssen verbindungsunterbrochene Ereignisse abonnieren, um auf getrennte Verbindungen zu reagieren. Sie müssen eine gewisse Redundanzstufe auf dem Client einrichten, um sicherzustellen, dass keine Nachrichten verloren gehen. Ich schlage vor, wie oben, dass Sie einen Dienst einführen, der spezifisch RabbitMQ befragen soll. Ihr Client kann versuchen, eine Nachricht an die letzte bekannte aktive Verbindung zu senden. Sollte dies fehlschlagen, fordert der Client den Überwachungsdienst möglicherweise auf, eine aktuelle Liste des RabbitMQ-Clusters zu erstellen. Unter der Annahme, dass es mindestens einen aktiven Knoten gibt, kann der Client dann eine Verbindung zu ihm herstellen und die Nachricht erfolgreich veröffentlichen.

Selbst mit all diesen Nachrichten noch verloren gehen können, weil sie auf der Durchreise sein können, wenn ich einen Knoten

Es gibt bestimmte Ränder Fälle töten, die Sie nicht mit Redundanz abdecken können, und keines kann RabbitMQ. Wenn beispielsweise eine Nachricht in einer Warteschlange landet und die HA-Richtlinie einen Hintergrundprozess aufruft, um die Nachricht an einen Sicherungsknoten zu kopieren. Während dieses Prozesses besteht die Möglichkeit, dass die Nachricht verloren geht, bevor sie auf dem Backup-Knoten gespeichert wird. Sollte der aktive Knoten sofort ausfallen, wird die Nachricht endgültig verloren gehen. Da kann nichts getan werden. Wenn wir uns auf die Ebene der tatsächlichen Bytes begeben, die über die Leitung laufen, gibt es leider eine Grenze für die Anzahl der Sicherheitsvorkehrungen, die wir erstellen können.

Daher müssen Consumer-Anwendungen Deduplizierung durchführen oder eingehende Nachrichten in einer idempotenten Weise bearbeiten.

Sie können eine Reihe von Möglichkeiten nutzen. Wenn Sie beispielsweise message-ttl auf einen relativ niedrigen Wert setzen, wird sichergestellt, dass doppelte Nachrichten nicht für längere Zeit in der Warteschlange verbleiben. Sie können jede Nachricht auch mit einer eindeutigen Referenz versehen und diese Referenz auf Consumer-Ebene überprüfen. Natürlich würde dies erfordern, einen Cache verarbeiteter Nachrichten zu speichern, um eingehende Nachrichten mit zu vergleichen; Die Idee ist, dass, wenn eine zuvor verarbeitete Nachricht ankommt, ihr Tag vom Verbraucher zwischengespeichert wurde und die Nachricht ignoriert werden kann.

Eine Sache, die ich mit AMQP und Queue-basierten Lösungen im Allgemeinen betonen möchte, ist, dass Ihre Infrastruktur die Tools bereitstellt, aber nicht die gesamte Lösung. Sie müssen diese Lücken basierend auf Ihren geschäftlichen Anforderungen überbrücken. Oft wird die beste Lösung durch Versuch und Irrtum abgeleitet. Ich hoffe, dass meine Vorschläge nützlich sind. Ich blogge über eine Reihe von RabbitMQ Design-Lösungen hier, einschließlich der Probleme, die Sie erwähnt haben, here, wenn Sie interessiert sind.

+1

Danke Paul. Du bist ein Gott. Nur um sicher zu gehen, bevor ich zur Implementierung übergehe, kannst du das bitte bestätigen: 1) Ich kann immer noch HAProxy verwenden und Herausgeber bestätigt und ich werde keine Nachricht verlieren. Ich werde doppelte Nachrichten haben, die ich irgendwie entfernen muss. Ich werde Leistungsprobleme haben (aufgrund von zusätzlichen Sprüngen zum Master, wenn ich die Slaves zum ersten Mal erreiche), aber meine Daten werden "kugelsicher" sein. 2) Um die Leistung zu erhöhen, werde ich einen Überwachungsdienst erstellen, so dass ich meine Anfragen immer nur an den Master senden werde, aber ich muss immer noch mit Duplikaten umgehen. Vielen Dank. –

+1

Sie können immer noch HAProxy verwenden, aber es entstehen zusätzliche Netzwerk-Hops mit einer Round-Robin-Konfiguration. Wenn Sie eine gleichmäßige Lastverteilung erreichen möchten, lesen Sie dies bitte: http://insidethecpu.com/2014/11/17/load-balancing-a-rabbitmq-cluster/ Es ist sehr unwahrscheinlich, dass Sie doppelte Nachrichten erhalten.Ich denke, dass die Einstellung der Eigenschaft message-ttl ausreicht, um Duplikate zu entfernen, obwohl das Hinzufügen eines Referenz-Tags, wie ich bereits erwähnt habe, das Problem lösen wird. Ich werde eine RabbitMQ-Bibliothek in C# veröffentlichen, die in Kürze alle oben genannten Punkte erreicht. Beobachte meinen Blog weiterhin auf Updates. –

+1

Eigentlich hatte ich am Ende doppelte Nachrichten. Ich habe ein paar Tests durchgeführt, bei denen 10000 Nachrichten an einen 2-Knoten-Kaninchen-Cluster publiziert wurden. Ich habe einen Knoten getötet und 10011-10012 Nachrichten erhalten. Eine meiner konsumierenden API ist idempotent, also war das Endergebnis in Ordnung. Danke vielmals. –

Verwandte Themen