Event Sourcing, CQRS und Apache Kafka – What’s the fuzz

(Last Updated On: 9. April 2018)

Wie funktioniert Event Sourcing im Vergleich zu einer relationalen Datenbank?

Klassische Anwendungen erledigen Ihre Datenhaltung heutzutage über ein relationales Datenbankmanagementsystem wie etwa Oracle DB, MS SQL Server, SAP ASE, Sybase iQ, IBM DB2, Teradata u. v. m. Diese funktionieren nach dem Relationenmodell, das heißt Relationen werden in Form von Tabellen abgebildet, die miteinander in Beziehung stehen. Das Problem bei relationalen Datenbanken ist, dass die ihnen zugrunde legende Art und Weise, mit Daten umzugehen, destruktiv ist. Wenn Sie beispielsweise einen Datensatz aktualisieren, überschreiben Sie den alten Inhalt des Datensatzes und platzieren an dessen stelle einen neuen Datensatz, der komplett andersartige Inhalte haben kann. Der alte Inhalt des Datensatzes ist, wenn Sie ihn nicht an anderer Stelle revisioniert haben, unwiederbringlich verloren. Das wäre ungefähr so, als würden Sie in der Buchhaltung einen Buchungssatz mit Tip-Ex aus Ihren Büchern entfernen.

Nicht umsonst ist jedoch gerade dieser Ansatz in der Buchführung verboten. Der Verlauf von geschäftlichen Transaktionen muss aus den Büchern nachvollzogen werden können. Nehmen wir beispielsweise an, Sie überweisen einem Lieferanten versehentlich statt 1.000 € eine stolze Summe von 10.000 €. Es gibt nun verschiedene Arten, wie Sie sich die überschüssigen 9.000 € wieder holen können:

  • Sie stornieren die Buchung an den Lieferanten komplett, erhalten daher 10.000 € zurück., und überweisen 1.000 € erneut.
  • Sie bitten den Lieferanten um eine Rückzahlung i. H. v. 9.000 €
  • Sie bekommen die 9.000 € für zukünftige Aufträge gut geschrieben

Egal, welche der drei Methoden sie wählen: Jede einzelne davon führt zum Ziel. Wichtig für einen Wirtschaftsprüfer ist allerdings, dass nachvollziehbar ist, welchen Ursprung die einzelnen Transaktionen haben. Es ist beispielsweise für einen Wirtschaftsprüfer sehr wichtig zu verstehen, dass zunächst eine Überbezahlung i. H. v. 9.000 € statt gefunden hat, bevor Sie diese Summe in den Folgeaufträge gut geschrieben bekommen. In der Buchführung dürfen Daten also nicht verloren gehen, weil jeder einzelne Vorgang, der zu diesen Daten geführt hat, wertvoll ist.

Genau dieser Ansatz beschäftigt Unternehmen. Häufig ist nicht nur der aktuelle Datenbestand interessant, sondern der Verlauf, wie es zu diesem Datenbestand gekommen ist. Dies ist insbesondere bei der forensischen Analyse von Datenbetrug wichtig, da nur so nachvollziehbar ist, wie es dazu gekommen ist.

Nehmen wir einmal ein simples Beispiel. Sie betreiben einen Online-Shop in der Größenordnung von Amazon. Sie wollen in eine Analyse realisieren, wie hoch die Wahrscheinlichkeit ist, dass Kunden, die einen Artikel aus ihrem Warenkorb entfernen, einige Monate später wieder kommen und den Artikel dann später doch kaufen. Bei einer gewöhnlichen relationalen Datenbank könnten Sie diese Analyse im Nachhinein nicht fahren. Wieso? Na, gehen wir mal beispielhaft den Prozess durch, wie die Daten in einer relationalen Datenbank verarbeitet würden.

Sie sind Amazon-Kunde. Sie haben also ein Kunden-Konto und einen Warenkorb. In einer relationalen Datenbank würde dies, sehr einfach dargestellt, so aussehen. Es gibt eine Tabelle Kunden, in welcher Ihr Kunden-Datensatz gespeichert ist, eine Tabelle Warenkörbe, in welcher Ihr Warenkorb abgelegt ist und eine Tabelle Artikel, in welcher alle Artikel gespeichert sind

Tabelle Kunden
Kunden-IDVornameNachnameGeburtsdatum
1AndreasLoibl21.08.1989

 

Tabelle Warenkörbe
Kunden-IDArtikel-IDMenge
1110
1225

 

Tabelle Artikel
Artikel-IDArtikel-BezeichnungBeschreibungPreis
1ComputermausAbsolut beste Computermaus auf der Welt10 €
2ComputertastaturAbsolut beste Computertastatur auf der Welt20 €

Sie sehen: Für einen Warenkorb gibt es für jeden Artikel, den Sie in den Warenkorb einbringen, einen Datensatz, bestehend au sihrer Kunden-ID, der Artikel-ID des Artikels und der Menge, die Sie in den Warenkorb gelegt haben.

Jetzt führen wir zwei Aktionen durch. Sie reduzieren die Menge der zu kaufenden Computermäuse von 10 auf 5 und nehmen die Computertastaturen komplett aus dem Warenkorb raus. Das einzige, was sich ändert, ist die tabelle Warenkörbe. Diese sieht nun so aus.

Tabelle Warenkörbe
Kunden-IDArtikel-IDMenge
115

Sie schließen den Kauf nun ab. dadurch, dass Sie die bestellung abschließen, wird die Tabelle Warenkörbe geleert, und dafür wird ein Eintrag in der Tabelle Bestellungen vorgenommen.

Tabelle Bestellungen
Bestellungs-IDArtikel-IDKunden-IDMenge
1115

Falls Sie mit dem Relationenmodell bzw. dem Entity Relationship Model (ERM) vertraut sind, nageln Sie mich jetzt nicht auf die Normalenform fest. Man könnte mitunter noch Daten einsparen, indem man dem Warenkorb eine ID vergibt und bei der Bestellung nur noch auf einen Warenkorb verweist. Bei der nächsten Bestellung des Kunden erhält dieser einen neuen Warenkorb mit einer neuen ID. Aber bleiben Sie mit mir bei diesem Beispiel.

Jetzt kehren wir zurück zu unserer Ausgangfrage. Wenn Sie jetzt 3 Monate später zurück kommen und die 20 Computertastaturen und die 5 übrigen Computermäuse doch kaufen, wie will Amazon fest stellen, dass Sie die Artikel zuvor in Ihrem Warenkorb hatten? Richtig, gar nicht, denn die Informationen sind verloren gegangen, als sie ihren Warenkorb aktualisiert haben. Und das ist das Kernproblem bei einer destruktiven Datenhaltung:

Sie können heute keine Aussage darüber treffen, wie viel Daten, die Sie aufgrund einer destruktiven Datenhaltung verloren haben, 5 Jahre später wert sein können.

Was glauben Sie denn, wie wertvoll es für den Online-Shop, der seit 20 Jahren existiert, wäre, genau diese Analyse jetzt mit den Daten der letzten 20 Jahre durchzuführen? Enorm wertvoll, denn dann liesse sich beispielsweise auswerten

  • wie wahrscheinlich es nach Jahren ist, dass Kunden nach einigen Monaten wieder kommen und einen Artikel doch kaufen
  • wie sich die Volatilität der Zielgruppe über die Jahre entwickelt hat (neigen jüngere Leute eher dazu, Liegen gelassene Artikel irgendwann wieder zu kaufen?)
  • Wie entwickelt sich das Verhalten der Bestandskunden über die Jahre (Haben Kunden, die in jungen Jahren noch liegen gelassene Artikel später doch gekauft haben, dieses Verhalten im fortgeschrittenen Alter abgelegt?)

Diese Erkenntnisse können sie mit einem klassischen relationalen Datenbankmanagementsystem nicht gewinnen, wenn Sie sich nicht um die Revisionierung dieser Daten gekümmert haben.

Verstehen Sie mich nicht falsch. Auch heutige ERP-Systeme, die auf relationalen Datenbanken basieren, revisionieren Daten. Wenn beispielsweise ein Datensatz in einer Datenbank, etwa ein Bestellvorgang, bearbeitet wird, kümmert sich das Anwendungssystem darum, dass die Daten revisionssicher aufbewahrt werden. so wird nicht der ursprüngliche Transaktionsvorgang einfach überschrieben, sondern es wird ein neuer Transaktionsvorgang angelegt, der auf den alten verweist. Auch Datenbankmanagementsysteme wie SAP HANA sind dazu in der Lage, Tabellen revisionssicher zu halten. Jede mal, wenn ein Datensatz in einer Tabelle eingefügt, verändert oder aus dieser gelöscht wird, legt die Datenbank eine Revision der Tabelle an. Anhand einer Revisionsnummer können dann die vorherigen Versionen der Tabelle wiederhergestellt werden. Deswegen wäre die Aussage, relationale Datenbankmanagementsysteme wären nicht revisionsfähig, falsch.

Wie löst nun Event Sourcing dieses Problem? Nun, Event Souring basiert nicht auf Datensätzen, sondern auf Events. Das heißt, im Event Sourcing werden, einfach ausgedrückt, folgende Tätigkeiten im Event Log gespeichert

  • Kunde mit der ID 1 legt Artikel mit der ID  1 in der Menge 10 in seinen Warenkorb
  • Kunde mit der ID 1 legt Aritkel mit der ID 2 in der Menge 20 in seinen Warenkorb
  • Kunde mit der ID 1 reduziert die Menge des Artikels mit der ID 1 in seinem Warenkorb um -5
  • Kunde reduziert die Menge des Artikels mit der ID 2 in seinem Warenkorb um -20

Wenn der Kunde nun in seiner Weboberfläche seinen Warenkorb aufruft, macht der Online Shop folgendes. Er geht in das Event Log und spielt alle Events ein, die sich auf den Warenkorb des Kunden beziehen.  Es ist vollkommen egal, wozu diese Events später benutzt werden. Wenn nun der Kunde sich den aktuellen Stand seines Warenkorbs anzeigen lassen will, schreibt ein Entwickler eine View dazu. Diese View sagt:

  • durchsuche das Event Log nach allen Events, die mit dem Kunden mit der ID 1 zu tun haben und die noch nicht in eine Bestellung verschoben wurden.
  • Durchlaufe diese Events eine nach dem anderen, und berechne auf Basis dieser Events das Endresultat das Warenkorbs.

Wenn nun hingegen der Online Shop Betreiber analysieren will, wie viele Kunden einen abgelegten Artikel neu gekauft haben, wird eine andere View erstellt.

  • Durchsuche das Event Log nach allen Events, in denen Kunden mit beliebiger ID einen Artikel mit beliebiger ID aus dem Warenkorb entfernt haben.
  • Durchsuche das Event Log nach allen Events, in denen Kunden mit beliebiger ID einen Artikel mit beliebiger ID in den Warenkorb gelegt und anschließend in eine Bestellung überführt haben
  • Ermittle alle Events, in denen der selbe Artikel zuvor einmal aus dem Warenkorb entfernt wurde.
  • Zeige die Menge dieser Vorgänge an

Event Sourcing ist da schlanker. Beim Event Sourcing wird der aktuelle Datenbestand immer aus der Menge an Events abgeleitet, die im System verarbeitet wurden.

Was ist nun der Vorteil dieses Vorgehens im Vergleich zur Umsetzung der Revisionsfähigkeit über eine relationale Datenbank? Nun, beim Event Sourcing können Sie die View zur Analyse des Benutzer-Kaufverhaltens heute, am 09.04.2018, bauen, und damit die Daten der letzten 20 Jahre analysieren. Bei der relationalen Datenbanken, welche die Historie auf die Datensätze baut, müssen Sie die Revisionsfähigkeit des Warenkorbs von Anfang an bedacht haben, also zu dem Zeitpunkt vor 20 Jahren, an dem sie den Online-Shop in Betrieb genommen haben. Ansonsten können Sie diese in der Vergangenheit liegenden Vorgänge nämlich nicht mehr analysieren.

Was ist Apache Kafka und CQRS?

Apache Kafka ist eine Persistierungs-Engine für Event Sourcing, also ein hochperformantes Event Log. Das was eine relationale Datenbank für den Online Shop wäre, ist in unserem Fall eine Event Log Engine wie Apache Kafka. Der Umgang mit Kafka bedeutet eine hohe Lernkurve. Programmierer müssen Ihre Denkweise umstellen. So müssen Sie nun Views und Aggregate auf Basis von Event Logs bauen, anstelle klassische SQL-Statements abzusetzen. Ein Webentwickler muss, um eine Webanwendung auf Basis von Event Sourcing umzustezen, neue Design Patterns adaptieren. Das wichtigste Entwurfsmuster ist Command Query Responsibility Segregation (CQRS). Bei CQRS wird eine Anwendung in zwei Teile gespalten. Das System, welches die Events erzeugt und somit Änderungen an den Enditäten (wie etwa Kunden, Warenkörbe und Bestellungen) auslöst, und das System, welches Informationen aus dem Event Log abruft, ohne dabei Daten zu vernichten. Klassischerweise kümmert sich die persistierende, also schreibende Seite der Anwendung, nur um eine möglichst vollständige Ablage aller Informationen. Diese Seite kümmert sich nicht darum, ob die Daten schnell aus dem Event Log abgerufen werden können, oder ob diese möglichst kosteneffizient gespeichert werden.

Der lesende Teil der Applikation hingegen kümmert sich darum, dass die Daten möglichst performant aus der Anwendung gelesen werden können. Der lesende Teil der Anwendung wird in Form von Views realisiert, die dem Event Log folgen, wie einem RSS Feed oder einem Newsletter. Die View baut darauf hin eine materialisierte Ansicht der Ereignisse im Event Log auf, so dass diese Daten abrufbar sind, als würden sie als Datensatz in einer Datenbank gespeichert sein. Der Vorteil dieses Vorgehens ist: Schreib- und Lesezugänge können getrennt voneinander skaliert werden. Sind die Schreibvorgänge der Anwendung zu langsam, kann etwas an der Persistenz-Schicht im Event Log getan werden, sind die Lesezugänge zu langsam, kann die Generierung der Views angepasst oder parallelisiert werden.

So kann die Lese-Engine der Anwendung die Daten beispielsweise in Graph-Datenbank wie neo4j auslagern, oder eine Such-Engine wie Lucene nutzen. In Umgebungen, die in hohem Maße auditierbar und damit revisionssicher sein müssen, kann das Event Log beispielsweise auf einen WORM-Speicher hinterlegt werden. Somit liegt das Event Log auf einem Write Once Read Many Device, das heißt jeder einzelne Zwischenstand des Event Logs selbst ist in sich noch einmal revisionsfähig. Auditoren und Wirtschaftsprüfer lieben das. Und das passiert nun, ohne die Leseperformance der Anwendung negativ zu beeinträchtigen. Genial.

 

Andreas Loibl ist SAP-Berater, Ethical Hacker und Online Marketing Manager und schreibt auf seinem Blog DaFRK Blog über verschiedene Themen in den Sektoren Projektmanagement, Informationstechnik, Persönlichkeitsentwicklung, Finanzen und Zeitmanagement.

DaFRK

Andreas Loibl ist SAP-Berater, Ethical Hacker und Online Marketing Manager und schreibt auf seinem Blog DaFRK Blog über verschiedene Themen in den Sektoren Projektmanagement, Informationstechnik, Persönlichkeitsentwicklung, Finanzen und Zeitmanagement.

Das könnte Dich auch interessieren …

1 Antwort

  1. 24. Mai 2018

    […] unnötige Kosten. Das Problem dabei ist jedoch auch, dass Sie heute nicht sagen können, was Daten, die Ihnen heute als unnütz erscheinen, in 5 Jahren vielleicht wert sein können. Eine gängige Aussage in Zusammenhang mit Big Data ist auch: „es ist günstiger, alles zu […]

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.