5

Wer weiß von einer Nachrichtenbusimplementierung, die granulare Kontrolle über Konsistenzgarantien bietet? Volle ACID ist zu langsam und keine ACID ist zu falsch.Suchen Sie nach Nachrichtenbusimplementierungen, die etwas zwischen voller ACID und nichts bieten

Wir verwenden derzeit Rhino ESB um MSMQ für unsere Messaging. Wenn Sie dauerhaftes transaktionales Messaging mit verteilten Transaktionen verwenden, kann MSMQ das Commit für eine beträchtliche Zeit blockieren, während es auf die E/A-Beendigung wartet.

Unsere Nachrichten fallen in zwei allgemeine Kategorien: Geschäftslogik und Denormalisierung. Letztere machen einen erheblichen Prozentsatz des Nachrichtenbusverkehrs aus.

Business-Logik-Nachrichten erfordern die Garantien der vollen ACID und MSMQ hat sich als ausreichend erwiesen.

Entnormierung Nachrichten:

  1. muss dauerhaft sein.
  2. darf nicht verarbeitet werden, bis die ursprüngliche Transaktion abgeschlossen ist.
  3. kann mehrmals verarbeitet werden.
  4. KÖNNEN verarbeitet werden, auch wenn die ursprüngliche Transaktion zurückgesetzt wird, solange 2) eingehalten wird.

(In einigen speziellen Fällen die Haltbarkeit Anforderungen wahrscheinlich gelockert werden könnte, aber die Identifizierung und die Fälle als Ausnahmen von der Regel Komplexität fügt Handhabung.)

Alle Denormalisation Nachrichten-Prozess behandelt werden, so dass keine ist Notwendigkeit für IPC.

Wenn der Prozess neu gestartet wird, kann davon ausgegangen werden, dass alle Transaktionen abgeschlossen (Commit oder Rollback) und alle Denormierungsnachrichten, die noch nicht verarbeitet wurden, wiederhergestellt werden müssen. Es ist akzeptabel, Denormalisierungsnachrichten wiederzugeben, die bereits verarbeitet wurden.

Soweit ich sagen kann, tendieren Messaging-Systeme, die mit Transaktionen umgehen, in der Regel die Wahl zwischen voller ACID oder nichts, und ACID trägt eine Leistungseinbuße. Wir sehen Aufrufe von TransactionScope # Commit(), die abhängig von der Anzahl der gesendeten Nachrichten in manchen Fällen einige hundert Millisekunden dauern.

Die Verwendung einer nicht transaktionalen Nachrichtenwarteschlange führt dazu, dass Nachrichten verarbeitet werden, bevor ihre ursprüngliche Transaktion abgeschlossen wird, was zu Konsistenzproblemen führt. Ein anderer Teil unseres Systems, der ähnliche Konsistenzanforderungen aber eine geringere Komplexität aufweist, verwendet bereits eine benutzerdefinierte Implementierung von etwas, das einem Transaktionsprotokoll ähnelt, und eine Verallgemeinerung, dass für diesen Anwendungsfall eine Option ist, würde ich aber lieber nicht implementieren ein kurzlebiges, gleichmäßiges, dauerhaftes, transaktionales Nachrichtensystem selbst, wenn ich nicht muss: Wenn jemand sich wundern mag, ist der Grund für das Erfordernis der Dauerhaftigkeit von Denormalisierungsnachrichten, dass das Erkennen von Desyncs und das Fixieren von Desyncs extrem schwierig sein kann und extrem teuer. Menschen tun beachten Sie, wenn etwas leicht falsch ist und eine Seite aktualisieren es nicht beheben, so Ignorieren desyncs ist keine Option.

Antwort

0

Es stellt sich heraus, dass MSMQ + SQL + DTC nicht einmal die Konsistenz Garantien bieten, die wir brauchen. Wir hatten zuvor ein Problem, bei dem Nachrichten verarbeitet wurden, bevor die verteilte Transaktion, die sie in die Warteschlange gestellt hatte, in die Datenbank übernommen wurde, was zu veralteten Lesevorgängen führte. Dies ist ein Nebeneffekt der ReadCommitted Isolation mit der Warteschlange zu verbrauchen, da:

  1. Starten Sie die Transaktion A.
  2. aktualisieren Datenbanktabelle in A.
  3. Queue Nachricht in A.
  4. Antrag Commit A.
  5. Nachrichtenwarteschlange begeht ein
  6. Starten Sie die Transaktion B.
  7. lesen Nachricht in B.
  8. Lesen der Datenbanktabelle in B unter Verwendung von ReadCommitted < - erhält Pre-A-Daten.
  9. Datenbank verpflichtet A.

Unsere Voraussetzung ist, dass auf A der B Lesen des Tabellenblocks verpflichten, die Serializable Transaktionen erfordert, die eine Leistungseinbuße führt.

Es sieht so aus, als wäre es normal, die notwendigen Einschränkungen zu implementieren und sich selbst zu garantieren, auch wenn es sich anhört, das Rad neu zu erfinden.

Hat jemand irgendwelche Kommentare dazu?

+0

Beschlossen, Nachrichtenbus-Transaktionen von Datenbanktransaktionen zu trennen, indem eine dauerhafte In-Process-Warteschlange implementiert wird. Business-Logik-Nachrichten werden weiterhin nicht idempotent sein, aber die Transaktion, in der sie gesendet werden, betrifft nur die Nachrichtenwarteschlange und wird nur nach der auslösenden Datenbanktransaktion abgeschlossen. Dadurch wird die Konsistenz bei der ReadCommitted-Isolation sichergestellt. Die dauerhafte Warteschlange wird auch verwendet, um Denormalisierungsvorgänge auszulösen, statt sie über MSMQ zu senden. –

1

Es ist nicht genau die Antwort, die Sie suchen, aber Jonathan Oliver geschrieben hat ausführlich darüber, wie mit verteilten Transaktionen in Messaging zu vermeiden und dennoch Transaktionsintegrität aufrechterhalten:

http://blog.jonathanoliver.com/2011/04/how-i-avoid-two-phase-commit/ http://blog.jonathanoliver.com/2011/03/removing-2pc-two-phase-commit/ http://blog.jonathanoliver.com/2010/04/idempotency-patterns/

Nicht Sicher, ob dir das hilft, aber hey.

+0

Danke für die Links. Ich kenne die verschiedenen Möglichkeiten, die Notwendigkeit von 2PC zu vermeiden, aber wir behalten eine ältere Codebase bei, die nicht auf Skalierbarkeit ausgelegt ist. Die Architektur ist immer noch eine Mischung aus alt und neu (und wird für die absehbare Zukunft sein). Bis wir die letzten Überreste des alten Codes loswerden können, brauchen wir verteilte Transaktionen, um alles konsistent zu halten. –

+0

Unser Denormalisierungssystem behandelt tatsächlich doppelte Nachrichten wie in diesen Links vorgeschlagen, aber wir müssen die Verarbeitung verzögern, bis die ursprüngliche Transaktion abgeschlossen ist. Ich weiß, wie ich all das selbst implementieren kann, aber ich versuche, eine vorhandene Bibliothek zu verwenden, um es für mich zu handhaben, wenn es möglich ist. –