Momentaufnahme- und Wiederherstellungsstrategien

8

Ich habe über CQRS+EventSoucing Muster gelesen (was ich in naher Zukunft anwenden möchte) und ein Punkt, der allen Decks und Präsentationen gemeinsam ist, ist Schnappschüsse von deinem Modellzustand zu machen, um ihn wiederherzustellen, aber Keiner von diesen teilt Muster / Strategien, dies zu tun.

Ich frage mich, ob Sie Ihre Gedanken und Erfahrungen in dieser Angelegenheit insbesondere in Bezug auf Folgendes teilen könnten:

  • Wann sollte ein Snapshot erstellt werden?
  • So modellieren Sie einen Snapshot-Speicher
  • Anwendung / Cache-Kaltstart

TL; DR: Wie haben Sie Snapshotting in Ihrer CQRS+EventSourcing -Anwendung implementiert? Vor- und Nachteile?

    
Mikhas 24.06.2016, 20:37
quelle

2 Antworten

6

Es gibt einige wenige Fälle, in denen Sie sicher Snapshots erstellen müssen. Aber es gibt ein Paar - ein häufiges Beispiel ist ein Konto in einem Hauptbuch. Sie werden Tausende, vielleicht Millionen von Kredit- / Debit-Ereignissen haben, die den endgültigen BALANCE -Zustand des Kontos erzeugen - es wäre verrückt, nicht so oft Snapshots zu erstellen.

Mein Ansatz für Snapshots, als ich Aggregates.NET entwarf, war standardmäßig deaktiviert um zu ermöglichen, dass Ihre Aggregate oder Entitäten von AggregateWithMemento oder EntityWithMemento erben müssen, wobei Ihre Entität wiederum eine RestoreSnapshot , eine TakeSnapshot und eine ShouldTakeSnapshot

definieren muss

Die Entscheidung, ob ein Schnappschuss gemacht werden soll oder nicht, bleibt der Entität selbst überlassen. Ein allgemeines Muster ist

%Vor%

Was natürlich alle 50 Ereignisse einen Schnappschuss machen würde.

Beim Lesen des Entity-Streams suchen wir zuerst nach einem Snapshot und lesen dann den Rest des Entity-Streams ab dem Moment, in dem der Snapshot erstellt wurde. IE: Fragen Sie nicht nach dem gesamten Stream, sondern nur nach dem Teil, den wir nicht aufgenommen haben.

Wie für den Laden - Sie können buchstäblich alles verwenden. VOU ist richtig, obwohl ein Schlüssel-Wert-Speicher am besten ist, weil Sie nur 1. überprüfen müssen, ob es einen gibt. 2. Laden Sie das ganze Ding - das ist ideal für kv

Bei Systemneustarts - ich befolge das, was Sie beschrieben haben, nicht wirklich. Es gibt keinen Grund dafür, dass Ihr Domänenserver in dem Sinne zustandsbehaftet ist, dass er zu verschiedenen Zeitpunkten etwas anderes tut. Es sollte nur 1 Sache machen - den nächsten Befehl verarbeiten. Bei der Verarbeitung eines Befehls lädt es Daten aus dem Ereignisspeicher, einschließlich eines Snapshots, führt den Befehl für die Entität aus, die entweder eine Geschäftsausnahme oder Domänenereignisse erzeugt, die im Geschäft aufgezeichnet werden.

Ich denke, dass Sie versuchen, mit dieser Rede von Caching und Kaltstarts zu viel zu optimieren.

    
Charles 25.06.2016, 15:26
quelle
5
  • Regel # 1: Nicht.
  • Regel # 2: Nicht.

Das Snapshot eines ereignisbezogenen Modells ist eine Leistungsoptimierung. Die erste Regel der Leistungsoptimierung? Nicht.

Insbesondere verringert Snapshot die Zeit, die Sie in Ihrem Repository verlieren, wenn Sie versuchen, den Verlauf Ihres Modells von Ihrem Ereignisspeicher aus neu zu laden.

Wenn Ihr Repository das Modell im Speicher behalten kann, werden Sie es nicht sehr oft neu laden. Der Gewinn durch Snapshotting wird also gering sein. Deshalb: nicht.

Wenn Sie Ihr Modell in aggregates zerlegen können, was bedeutet, dass Sie den Verlauf Ihres Modells in eine Anzahl von Entitäten mit nicht überlappenden Historien zerlegen können, dann wird Ihr Modell lange Modellhistorie viel zu kurz Historien, die jeweils die Änderungen an einer einzelnen Entität beschreiben. Jeder Entity-Verlauf, den Sie laden müssen, ist ziemlich kurz, so dass der Gewinn aus einem Snapshot gering ist. Deshalb: nicht.

  

Die Art von Systemen, die ich heute arbeite, erfordert hohe Leistung, aber keine 24x7-Verfügbarkeit. In einer Situation, in der ich mein System für die Wartung herunterfahre und neu starte, müsste ich meinen gesamten Ereignisspeicher laden und neu verarbeiten, da mein neues System nicht weiß, welche Aggregat-IDs die Ereignisse verarbeiten sollen. Ich brauche einen besseren Ausgangspunkt für meine Systeme, um effizienter zu starten.

Sie machen sich Sorgen darüber, dass Sie einen Schreib-SLA verpassen, wenn die Caches des Repository-Speichers kalt sind, und Sie haben lange Modellhistorien mit vielen zu aktualisierenden Ereignissen. Das Erstellen von Snapshots kann viel sinnvoller sein als der Versuch, die Modellhistorie in kleinere Streams umzuwandeln. OK ....

Der Snapshot-Speicher ist ein Lesemodell - zu jedem Zeitpunkt sollten Sie in der Lage sein, das Modell wegzublasen und es aus der beibehaltenen Historie im Ereignisspeicher wiederherzustellen.

Aus Sicht des Repository ist der Snapshot-Speicher ein Cache; Wenn kein Snapshot verfügbar ist oder wenn der Informationsspeicher selbst nicht innerhalb des SLA antwortet, möchten Sie ausgehend vom ursprünglichen Startstatus auf die erneute Verarbeitung des gesamten Ereignisverlaufs zurückgreifen.

Die Benutzeroberfläche des Dienstanbieters sieht ungefähr wie

aus %Vor%

SnapshotRecord wird dem Repository die Informationen zur Verfügung stellen, die es benötigt, um den Snapshot zu verwenden. Das wird mindestens enthalten

  1. ein Memento , das dem Repository ermöglicht, den Snapshot-Status
  2. zu rehydrieren
  3. eine Beschreibung des letzten Ereignisses, das vom Schnappschussprojektor beim Erstellen des Schnappschusses verarbeitet wurde.

Das Modell hydratisiert dann den Schnappschussstatus aus dem Memento, lädt den Verlauf aus dem Ereignisspeicher, sucht rückwärts (dh beginnend mit dem letzten Ereignis) nach dem in dokumentierten Ereignis SnapshotRecord, dann wenden Sie die nachfolgenden Ereignisse der Reihe nach an.

Das SnapshotRepository selbst könnte ein Schlüssel / Wert-Speicher sein (höchstens ein Datensatz für eine gegebene ID), aber eine relationale Datenbank mit Blob-Unterstützung funktioniert auch gut

%Vor%

Der Snapshot-Projektor und das Repository sind eng miteinander verbunden - sie müssen sich darauf einigen, wie der Zustand der Entität für alle möglichen Geschichten sein soll, sie müssen sich darauf einigen, wie sie das Memento entfeuchten und was sie tun müssen stimme zu, welche ID verwendet wird, um den Snapshot zu finden.

Die enge Kopplung bedeutet auch, dass Sie sich nicht besonders um die Schema für das Memento; Ein Byte-Array ist in Ordnung.

Sie müssen jedoch nicht mit früheren Inkarnationen ihrer selbst übereinstimmen. Snapshot Projector 2.0 verwirft / ignoriert alle Snapshots, die von Snapshot Projector 1.0 zurückgelassen wurden - der Snapshot-Speicher ist schließlich nur ein Cache .

  

Ich entwerfe eine Anwendung, die wahrscheinlich Millionen von Ereignissen pro Tag generieren wird. Was können wir tun, wenn wir 6 Monate später eine Ansicht neu erstellen müssen?

Eine der überzeugendsten Antworten hier ist, Zeit explizit zu modellieren. Haben Sie eine Entität, die für sechs Monate lebt, oder haben Sie 180 Entitäten, die jeweils einen Tag lang leben? Das Rechnungswesen ist eine gute Domäne, auf die hier Bezug genommen werden kann: Am Ende des Geschäftsjahres werden die Bücher geschlossen, und die Bücher des nächsten Jahres werden mit den Übertragungen eröffnet.

Yves Reynhout spricht häufig über Modellierungszeit und -planung; Die Entwicklung eines Modells kann ein guter Ausgangspunkt sein.

    
VoiceOfUnreason 24.06.2016 22:21
quelle

Tags und Links