2014-04-24 17 views
21

Was ist der beste Weg, um doppelte Nachrichten in Amazon SQS zu verhindern? Ich habe ein SQS von Domains, die darauf warten, gecrawlt zu werden. Bevor ich eine neue Domäne zur SQS hinzufüge, kann ich mit den gespeicherten Daten prüfen, ob sie kürzlich gecrawlt wurde, um Duplikate zu verhindern.So verhindern Sie doppelte SQS-Nachrichten?

Das Problem ist mit den Domänen, die bisher noch nicht gecrawlt. Zum Beispiel, wenn sich in der Warteschlange 1000 Domänen befinden, die nicht gecrawlt wurden. Jeder dieser Links könnte wieder und wieder und wieder hinzugefügt werden. Was meine SQS zu Hunderttausenden von Nachrichten anschwillt, die hauptsächlich Duplikate sind.

Wie verhindere ich das? Gibt es eine Möglichkeit, alle Duplikate aus einer Warteschlange zu entfernen? Oder gibt es eine Möglichkeit, eine Warteschlange nach einer Nachricht zu durchsuchen, bevor ich sie hinzufüge? Ich denke, das ist ein Problem, das jeder mit einer SQS erlebt haben muss.

Eine Option, die ich sehen kann, ist, wenn ich einige Daten speichern, bevor die Domäne der SQS hinzugefügt wird. Aber wenn ich die Daten zweimal speichern muss, ruiniert das irgendwie den Sinn der Verwendung eines SQS an erster Stelle.

+0

Mögliches Duplikat von [Verwendung vieler Konsumenten in der SQS-Warteschlange] (http://stackoverflow.com/questions/37472129/using-many-consumers-in-sqs-queue) – Krease

+1

AWS bietet jetzt [fifo queues] (http: //docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html), die "genau einmal Verarbeitung, aber sind auf 300 Transaktionen pro Sekunde begrenzt". – bishop

Antwort

15

Wie die anderen Antworten erwähnt, können Sie nicht verhindern, dass doppelte Nachrichten von SQS kommen.

In den meisten Fällen werden Ihre Nachrichten einmal an einen Ihrer Kunden weitergeleitet, aber Sie werden irgendwann in Duplikate laufen.

Ich glaube nicht, dass es eine einfache Antwort auf diese Frage gibt, denn es erfordert, eine richtige Architektur zu entwickeln, die mit Duplikaten zurechtkommt, was bedeutet, dass sie in der Natur idempotent ist.

Wenn alle Mitarbeiter in Ihrer verteilten Architektur idempotent wären, wäre das einfach, da Sie sich keine Gedanken über Duplikate machen müssten. Aber in Wirklichkeit existiert diese Art von Umgebung nicht, irgendwo wird etwas nicht damit umgehen können.

Ich arbeite gerade an einem Projekt, bei dem es von mir verlangt wird, dies zu lösen und einen Ansatz zu entwickeln. Ich dachte, es könnte anderen helfen, meine Gedanken hier zu teilen. Und es könnte ein guter Ort sein, um ein Feedback zu meinem Denken zu bekommen.

Fact store

Es ist eine ziemlich gute Idee, Dienstleistungen zu entwickeln, so dass sie Fakten sammeln, die theoretisch wiedergegeben werden kann, den gleichen Zustand in allen betroffenen nachgelagerten Systemen zu reproduzieren.

Zum Beispiel, sagen wir mal Sie einen Message-Broker für eine Aktie Handelsplattform bauen. () Ich habe tatsächlich an einem Projekt wie diesem gearbeitet, es war schrecklich, aber auch eine gute Lernerfahrung.)

Lassen Sie uns jetzt sagen, dass das kommen in Handel, und es gibt drei Systeme daran interessiert:

  1. Ein altbewährter Mainframe, die
  2. Ein System bleiben muss aktualisiert, die alle Gewerke sammelt und teilen sie es mit Partnern auf einem FTP-Server
  3. der Dienst, den Handel aufnimmt, und ordnet Aktien an den neuen Eigentümer

es ist ein bisschen gewunden, I k jetzt, aber die Idee ist, dass eine Nachricht (Tatsache) hereinkommt, hat verschiedene verteilte nachgelagerte Effekte.

Jetzt stellen wir uns vor, dass wir einen Tatsachenspeicher, eine Aufzeichnung aller in unseren Vermittler kommenden Trades unterhalten. Und dass alle 3 nachgeschalteten Service-Besitzer uns anrufen, um uns mitzuteilen, dass sie alle ihre Daten von den letzten 3 Tagen verloren haben. Der FTP-Download liegt 3 Tage zurück, der Mainframe liegt 3 Tage zurück und alle Trades liegen 3 Tage zurück.

Da wir den Faktspeicher haben, könnten wir theoretisch alle diese Nachrichten von einer bestimmten Zeit bis zu einer bestimmten Zeit wiederholen. In unserem Beispiel wäre das von vor 3 Tagen bis heute. Und die nachgelagerten Dienste könnten eingeholt werden.

Dieses Beispiel mag ein wenig übertrieben erscheinen, aber ich versuche, etwas ganz Besonderes zu vermitteln: Die Fakten sind die wichtigsten Dinge, die man verfolgen muss, weil wir in unserer Architektur Duplikate bekämpfen werden .

Wie die Tatsache, Speicher hilft uns, mit doppelten Nachrichten

Sofern Sie Ihr Fakt Speicher auf einem Persistenzschicht implementieren, dass Sie die CA Teile der CAP theorem, Konsistenz und Verfügbarkeit gibt, können Sie folgendes tun:

Sobald eine Nachricht von einer Warteschlange empfangen wird, checken Sie in Ihrem Faktendatenspeicher ein, ob Sie diese Nachricht bereits gesehen haben und ob sie im Moment gesperrt und in einem ausstehenden Status ist. In meinem Fall werde ich MongoDB verwenden, um meinen Faktenspeicher zu implementieren, da ich mich damit sehr wohl fühle, aber verschiedene andere DB-Technologien sollten damit umgehen können.

Wenn der Fakt noch nicht existiert, wird er in den Faktespeicher mit einem ausstehenden Status und einer Sperrverfallszeit eingefügt. Dies sollte mit atomaren Operationen geschehen, weil Sie nicht möchten, dass dies zweimal passiert! Hier stellen Sie sicher, dass Ihr Service idempotence ist.

Glückliche Fall - die meiste Zeit kommt zu sagen

Wenn die Tatsache Laden kommt es zu Ihren Diensten zurück, dass die Tatsache noch nicht existierte, und dass eine Sperre geschaffen wurde, versucht der Dienst es ist zu tun . Sobald es fertig ist, löscht es die SQS-Nachricht und markiert die Tatsache als abgeschlossen.

Doppelte Nachricht

Also das ist, was passiert, wenn eine Nachricht durch kommt und es ist kein Duplikat. Aber sehen wir uns an, wenn eine doppelte Nachricht eingeht. Der Dienst nimmt sie auf und fordert den Faktspeicher auf, sie mit einer Sperre aufzuzeichnen. Der Faktspeicher sagt ihm, dass er bereits existiert und dass er gesperrt ist. Der Dienst ignoriert die Nachricht und überspringt sie!Sobald die Nachrichtenverarbeitung vom anderen Mitarbeiter ausgeführt wurde, wird diese Nachricht aus der Warteschlange gelöscht und wir werden sie nicht mehr sehen.

Katastrophenfall - geschieht selten

Also, was passiert, wenn ein Service die Tatsache, zum ersten Mal in dem Laden aufzeichnet, dann eine Sperre für einen bestimmten Zeitraum bekommen, aber umfällt? Nun, SQS wird Ihnen erneut eine Nachricht präsentieren, wenn sie abgeholt wurde, aber nicht innerhalb einer bestimmten Zeit, nachdem sie aus der Warteschlange bedient wurde. Das ist der Grund, warum wir unseren Fakteladen so programmieren, dass ein Service für eine begrenzte Zeit eine Sperre aufrechterhält. Denn wenn es umkippt, möchten wir, dass SQS die Nachricht dem Dienst oder einer anderen Instanz zu einem späteren Zeitpunkt präsentiert, damit dieser Dienst annehmen kann, dass die Tatsache wieder in den Zustand (ausgeführt) aufgenommen werden sollte.

+0

Vielen Dank für Ihren Ansatz –

+0

Kein Problem, wenn Sie einen ähnlichen Ansatz annehmen und Probleme auftreten, lassen Sie es mich wissen. Ich könnte vielleicht helfen. – hendrikswan

+1

Super Antwort! Leichter Nitpick: Ich würde sagen, dass in der ** Happy Case ** Sie die Tatsache als abgeschlossen markieren sollten, und dann löschen Sie die SQS-Nachricht. Ich würde dann auch vorschlagen, die Nachricht ** Duplicate-Nachricht ** zu aktualisieren, um eine Nachricht zu löschen, wenn die Tatsache bereits als abgeschlossen markiert ist (warten Sie nicht, bis der ursprüngliche Handler es tut). –

2

Es gibt keine API-Ebene, die verhindert, dass doppelte Nachrichten in eine SQS-Warteschlange eingereiht werden. Sie müssten das auf Anwendungsebene handhaben, fürchte ich.

Sie können eine DynamoDB-Tabelle verwenden, um Ihre Domain-Namen zu speichern, die darauf warten, gecrawlt zu werden, und sie nur zur Warteschlange hinzufügen, wenn sie sich zum Beispiel nicht in DynamoDB befinden.

+2

Aber wenn ich das mache, warum überhaupt SQS überhaupt benutzen? Warum lassen Sie die Anwendung nicht direkt aus der DynamoDB lesen? Vielleicht missverstehe ich die Verwendung von SQS, aber wenn ich noch alle Daten in einer Datenbank speichern muss, habe ich das Gefühl, dass SQS seinen Wert und Punkt verliert. Der Grund, warum ich eine SQS verwenden möchte, ist, dass ich KEINE Daten in eine Datenbank schreiben muss. –

+1

Dies ist eine Architekturentscheidung. SQS (oder ein beliebiges Warteschlangensystem) eignet sich hervorragend für die asynchrone Kommunikation zwischen Anwendungen und dafür, dass mehrere Nachrichtenkonsumenten Nachrichten von mehreren Herstellern konsumieren. Beispiel wäre zwischen einer Web-Ebene und einer Flotte von Batch-Arbeitern. Die Datenbank ist nicht für diese Art von Kommunikation ausgelegt und würde zusätzliche Arbeit erfordern. Aber DB ist gut darin, den Status zwischen unabhängigen Mitarbeitern oder Apps zu teilen. In Ihrem Anwendungsfall wäre vielleicht eine Datenbank ausreichend. –

2

Wie Sie nicht SQS verhindern können die duplizierten Nachrichten senden können, müssen Sie diese auf Ihrer Seite implementieren. Ein einfacher Weg, dies zu tun, ist Apache Camels idempotente Konsumenten, siehe http://camel.apache.org/idempotent-consumer.html

Verwandte Themen