Bearbeiten

Teilen über


Saga verteiltes Transaktionsmuster

Azure

Das Saga-Designmuster trägt dazu bei, die Datenkonsistenz in verteilten Systemen aufrechtzuerhalten, indem Transaktionen über mehrere Dienste hinweg koordiniert werden. Eine Saga ist eine Sequenz lokaler Transaktionen, bei denen jeder Dienst seinen Betrieb ausführt und den nächsten Schritt durch Ereignisse oder Nachrichten initiiert. Wenn ein Schritt in der Sequenz fehlschlägt, führt die Saga Ausgleichstransaktionen durch, um die abgeschlossenen Schritte rückgängig zu machen. Dieser Ansatz trägt dazu bei, die Datenkonsistenz aufrechtzuerhalten.

Kontext und Problem

Eine Transaktion stellt eine Arbeitseinheit dar, die mehrere Vorgänge umfassen kann. Innerhalb einer Transaktion bezieht sich ein Ereignis auf eine Zustandsänderung, die sich auf eine Entität auswirkt. Ein -Befehl kapselt alle Informationen, die zum Ausführen einer Aktion oder auslösen eines nachfolgenden Ereignisses erforderlich sind.

Transaktionen müssen den Grundsätzen der Atomität, Konsistenz, Isolation und Haltbarkeit (ACID) entsprechen.

  • Atomität: Alle Vorgänge sind erfolgreich oder ohne Vorgänge erfolgreich.
  • Konsistenz: Datenübergänge von einem gültigen Zustand in einen anderen gültigen Zustand.
  • Isolation: Gleichzeitige Transaktionen liefern dieselben Ergebnisse wie sequenzielle Transaktionen.
  • Haltbarkeit: Änderungen bleiben nach dem Commit erhalten, auch wenn Fehler auftreten.

In einem einzigen Dienst folgen Transaktionen ACID-Prinzipien, da sie innerhalb einer einzelnen Datenbank arbeiten. Es kann jedoch komplexer sein, die ACID-Compliance über mehrere Dienste hinweg zu erreichen.

Herausforderungen in Microservices-Architekturen

Microservices-Architekturen weisen in der Regel jeder Microservice-einededizierte Datenbank zu. Dieser Ansatz bietet mehrere Vorteile:

  • Jeder Dienst kapselt seine eigenen Daten.
  • Jeder Dienst kann die am besten geeignete Datenbanktechnologie und das schema für seine spezifischen Anforderungen verwenden.
  • Datenbanken für jeden Dienst können unabhängig voneinander skaliert werden.
  • Fehler in einem Dienst sind von anderen Diensten isoliert.

Trotz dieser Vorteile erschwert diese Architektur die dienstübergreifende Datenkonsistenz. Herkömmliche Datenbankgarantien wie ACID gelten nicht direkt für mehrere unabhängig verwaltete Datenspeicher. Aufgrund dieser Einschränkungen sind Architekturen, die auf die Kommunikation zwischen verarbeitungsbezogener Oder herkömmlicher Transaktionsmodelle wie zweistufigem Commitprotokoll angewiesen sind, häufig besser für das Saga-Muster geeignet.

Lösung

Das Saga-Muster verwaltet Transaktionen, indem sie in eine Abfolge von lokalen Transaktionenunterteilt werden.

Diagramm, das eine Saga-Übersicht zeigt.

Jede lokale Transaktion:

  1. Schließt seine Arbeit atomisch innerhalb eines einzigen Diensts ab.
  2. Aktualisiert die Datenbank des Diensts.
  3. Initiiert die nächste Transaktion über ein Ereignis oder eine Nachricht.

Wenn eine lokale Transaktion fehlschlägt, führt die Saga eine Reihe von Ausgleichstransaktionen durch, die Änderungen rückgängig zu machen, die die vorherigen lokalen Transaktionen vorgenommen haben.

Schlüsselkonzepte im Saga-Muster

  • Kompensierbare Transaktionen können durch andere Transaktionen rückgängig gemacht oder kompensiert werden. Wenn ein Schritt in der Saga fehlschlägt, machen Ausgleichstransaktionen die Änderungen rückgängig, die die kompensierbaren Transaktionen vorgenommen haben.

  • Pivot-Transaktionen als Punkt ohne Rückgabe in der Saga dienen. Nachdem eine Pivottransaktion erfolgreich war, sind kompensierbare Transaktionen nicht mehr relevant. Alle nachfolgenden Aktionen müssen abgeschlossen werden, damit das System einen konsistenten Endzustand erreicht. Eine Pivottransaktion kann je nach Ablauf der Saga unterschiedliche Rollen annehmen:

    • unwiderrufliche oder nicht kompensierbare Transaktionen können nicht rückgängig gemacht oder wiederholt werden.

    • Die Grenze zwischen umkehrbarem und zugesicherten bedeutet, dass die Pivottransaktion die letzte rückgängig gemachte oder kompensierbare Transaktion sein kann. Oder es kann die erste retryable Operation in der Saga sein.

  • Retryable transactions follow the pivot transaction. Retryable transactions are idempotent and help ensure that the saga can reach its final state, even if temporary failures occur. Sie helfen der Saga schließlich, einen konsistenten Zustand zu erreichen.

Saga Implementierungsansätze

Die beiden typischen Saga-Implementierungsansätze sind Choreographie und Orchestrierung. Jeder Ansatz verfügt über eigene Herausforderungen und Technologien, um den Workflow zu koordinieren.

Choreographie

Im Choreographieansatz tauschen Dienste Ereignisse ohne zentralen Controller aus. Bei der Choreographie veröffentlicht jede lokale Transaktion Domänenereignisse, die lokale Transaktionen in anderen Diensten auslösen.

Diagramm, das eine Saga mit Choreographie zeigt.

Vorteile der Choreographie Nachteile der Choreographie
Gut für einfache Workflows, die nur wenige Dienste haben und keine Koordinationslogik benötigen. Workflow kann verwirrend sein, wenn Sie neue Schritte hinzufügen. Es ist schwierig zu verfolgen, auf welche Befehle jeder Saga-Teilnehmer reagiert.
Für die Koordination ist kein anderer Dienst erforderlich. Es besteht das Risiko einer zyklischen Abhängigkeit zwischen saga-Teilnehmern, da sie die Befehle der anderen nutzen müssen.
Führt keinen einzigen Fehlerpunkt ein, da die Verantwortlichkeiten über die Saga-Teilnehmer verteilt werden. Integrationstests sind schwierig, da alle Dienste ausgeführt werden müssen, um eine Transaktion zu simulieren.

Orchestrierung

Bei der Orchestrierung, einem zentralen Controller oder Orchestrator-werden alle Transaktionen verarbeitet und den Teilnehmern mitgeteilt, welche Operation basierend auf Ereignissen ausgeführt werden soll. Der Orchestrator führt Saga-Anforderungen aus, speichert und interpretiert die Zustände jeder Aufgabe und verarbeitet die Fehlerwiederherstellung mithilfe von Ausgleichstransaktionen.

Diagramm, das eine Saga mit Orchestrierung zeigt.

Vorteile der Orchestrierung Nachteile der Orchestrierung
Besser geeignet für komplexe Workflows oder beim Hinzufügen neuer Dienste. Andere Entwurfskomplexität erfordert eine Implementierung einer Koordinationslogik.
Vermeidet zyklische Abhängigkeiten, da der Orchestrator den Fluss verwaltet. Führt einen Fehlerpunkt ein, da der Orchestrator den vollständigen Workflow verwaltet.
Eine klare Trennung der Verantwortlichkeiten vereinfacht die Dienstlogik.

Probleme und Überlegungen

Berücksichtigen Sie die folgenden Punkte, wenn Sie sich für die Implementierung dieses Musters entscheiden:

  • Schicht im Designdenken: Die Übernahme des Saga-Musters erfordert eine andere Denkweise. Es erfordert, dass Sie sich auf die Transaktionskoordination und die Datenkonsistenz über mehrere Microservices konzentrieren.

  • Komplexität der Debugging-Sagas: Debugging-Sagas können komplex sein, insbesondere wenn die Anzahl der teilnehmenden Dienste wächst.

  • Unwiderrufliche lokale Datenbankänderungen: Daten können nicht zurückgesetzt werden, da die Saga-Teilnehmer Änderungen an ihren jeweiligen Datenbanken übernehmen.

  • Behandlung vorübergehender Fehler und Idempotenz: Das System muss vorübergehende Fehler effektiv behandeln und Idempotenz sicherstellen, wenn die wiederholung desselben Vorgangs das Ergebnis nicht ändert. Weitere Informationen finden Sie unter Idempotent-Nachrichtenverarbeitung.

  • Bedarf an Überwachungs- und Tracking-Sagas: Überwachung und Nachverfolgung des Workflows einer Saga sind wesentliche Aufgaben, um die operative Kontrolle aufrechtzuerhalten.

  • Einschränkungen der Ausgleichstransaktionen: Ausgleichstransaktionen sind möglicherweise nicht immer erfolgreich, was das System in einem inkonsistenten Zustand belassen kann.

Potenzielle Datenanomalien in Sagas

Datenanomalien sind Inkonsistenzen, die auftreten können, wenn Sagas über mehrere Dienste hinweg arbeiten. Da jeder Dienst seine eigenen Daten verwaltet, die Teilnehmerdatengenannt werden, gibt es keine integrierte Isolierung über Dienste hinweg. Diese Einrichtung kann zu Dateninkonsistenzen oder Dauerhaftigkeitsproblemen führen, z. B. teilweise angewendete Updates oder Konflikte zwischen Diensten. Typische Probleme sind:

  • Verlorene Updates: Wenn eine Saga Daten ändert, ohne änderungen von einer anderen Saga zu berücksichtigen, führt sie zu überschriebenen oder fehlenden Updates.

  • Dirty liest: Wenn eine Saga oder Transaktion Daten liest, die eine andere Saga geändert hat, aber die Änderung nicht abgeschlossen ist.

  • Fuzzy oder nicht wiederholbar liest: Wenn verschiedene Schritte in einer Saga inkonsistente Daten lesen, da Aktualisierungen zwischen den Lesevorgängen auftreten.

Strategien zur Behebung von Datenanomalien

Um diese Anomalien zu reduzieren oder zu verhindern, sollten Sie die folgenden Gegenmaßnahmen berücksichtigen:

  • Semantiksperre: Verwenden Sie Sperrungen auf Anwendungsebene, wenn die kompensierbare Transaktion einer Saga ein Semaphor verwendet, um anzugeben, dass ein Update ausgeführt wird.

  • Kommutative Updates: Designupdates, sodass sie in beliebiger Reihenfolge angewendet werden können und gleichzeitig dasselbe Ergebnis erzeugen. Dieser Ansatz hilft dabei, Konflikte zwischen Sagas zu reduzieren.

  • Pessimistische Ansicht: Die Reihenfolge der Saga neu anordnen, sodass Datenaktualisierungen in wiederholungsfähigen Transaktionen auftreten, um schmutzige Lesevorgänge zu beseitigen. Andernfalls könnte eine Saga schmutzige Daten lesen oder nicht genehmigte Änderungen, während eine andere Saga gleichzeitig eine kompensierbare Transaktion durchführt, um die Aktualisierungen zurückzufahren.

  • Werte für erneutes Lesen: Bestätigen Sie, dass die Daten unverändert bleiben, bevor Sie Aktualisierungen vornehmen. Wenn sich Daten ändern, beenden Sie den aktuellen Schritt, und starten Sie die Saga nach Bedarf neu.

  • Versionsdateien: Verwalten eines Protokolls aller vorgänge, die für einen Datensatz ausgeführt werden, und stellen Sie sicher, dass sie in der richtigen Sequenz ausgeführt werden, um Konflikte zu verhindern.

  • risikobasierte Parallelität basierend auf Wert: Wählen Sie dynamisch den entsprechenden Parallelitätsmechanismus basierend auf dem potenziellen Geschäftsrisiko aus. Verwenden Sie beispielsweise Sagas für Updates mit geringem Risiko und verteilte Transaktionen für Updates mit hohem Risiko.

Wann dieses Muster verwendet werden soll

Verwenden Sie dieses Muster in folgenden Fällen:

  • Sie müssen die Datenkonsistenz in einem verteilten System ohne enge Kopplung sicherstellen.
  • Sie müssen einen Rollback durchführen oder ausgleichen, wenn eine der Vorgänge in der Sequenz fehlschlägt.

Dieses Muster ist möglicherweise nicht geeignet, wenn:

  • Transaktionen sind eng gekoppelt.
  • Ausgleichstransaktionen treten in früheren Teilnehmern auf.
  • Es gibt zyklische Abhängigkeiten.

Nächster Schritt

Die folgenden Muster sind möglicherweise relevant, wenn Sie dieses Muster implementieren:

  • Das Choreographiemuster verfügt über jede Komponente des Systems an dem Entscheidungsprozess über den Workflow einer Geschäftstransaktion, anstatt sich auf einen zentralen Kontrollpunkt zu verlassen.

  • Das Kompensierungstransaktionsmusters Arbeit rückgängig, die von einer Reihe von Schritten ausgeführt wird, und definiert schließlich einen konsistenten Vorgang, wenn ein oder mehrere Schritte fehlschlagen. In der Cloud gehostete Anwendungen, die komplexe Geschäftsprozesse und Workflows implementieren, folgen häufig diesem späteren Konsistenzmodell.

  • Das Wiederholungsmuster ermöglicht es einer Anwendung, vorübergehende Fehler zu behandeln, wenn versucht wird, eine Verbindung mit einem Dienst oder einer Netzwerkressource herzustellen, indem der fehlgeschlagene Vorgang transparent wiederholt wird. Dieses Muster kann die Stabilität der Anwendung verbessern.

  • Das Circuit Breaker-Muster behandelt Fehler, die eine variable Zeit in Anspruch nehmen, aus der Sie eine Verbindung mit einem Remotedienst oder einer Ressource herstellen. Dieses Muster kann die Stabilität und Resilienz einer Anwendung verbessern.

  • Das Muster für die Integritätsendpunktüberwachung implementiert funktionale Prüfungen in einer Anwendung, auf die externe Tools in regelmäßigen Abständen über verfügbar gemachte Endpunkte zugreifen können. Mit diesem Muster können Sie überprüfen, ob Anwendungen und Dienste ordnungsgemäß ausgeführt werden.