it-swarm.com.de

Was sind die Nachteile bei der Verwendung von Event Sourcing und CQRS?

Event-Sourcing und CQRS sind großartig, da Entwickler vor einer modellierten Datenbank bleiben müssen, mit der der Entwickler während der gesamten Lebensdauer der Anwendung arbeiten muss, es sei denn, es gibt ein Big-Data-Migrationsprojekt. CQRS und ES bieten darüber hinaus weitere Vorteile wie das Skalieren von Eventstore, Prüfprotokoll usw., die bereits im gesamten Internet verfügbar sind.

Aber was sind die Nachteile?

Hier sind einige Nachteile, die ich mir vorstellen kann, nachdem ich kleine Demo-Apps recherchiert und geschrieben habe

  1. Complex: Manche sagen, dass ES komplex ist. Aber ich würde sagen, dass eine komplexe Anwendung besser ist als ein komplexes Datenbankmodell, für das Sie nur sehr eingeschränkte Abfragen mit einer Abfragesprache ausführen können (mehrere Joins, Indizes usw.). Ich meine, einige Programmiersprachen wie Scala verfügen über eine sehr umfangreiche Sammlungsbibliothek, die sehr flexibel ist, um einige sehr komplexe Aggregationen zu erstellen. Außerdem gibt es Apache Spark, mit dem verteilte Sammlungen einfach abgefragt werden können. Datenbanken sind jedoch immer auf die Abfragesprache beschränkt, und das Verteilen von Datenbanken ist schwieriger als der verteilte Anwendungscode (Stellen Sie einfach eine andere Instanz auf einem anderen Computer bereit!)
  2. Hohe Speicherplatzbelegung : Event-Store verwendet zum Speichern von Ereignissen möglicherweise viel Speicherplatz. Aber wir können alle paar Wochen eine Aufräumaktion durchführen und einen Snapshot erstellen. Vielleicht können wir historische Ereignisse lokal auf einer externen HD speichern, wenn wir alte Ereignisse in der Zukunft brauchen. 
  3. Hohe Speichernutzung : Der Status jedes Domänenobjekts wird im Speicher gespeichert, wodurch die Verwendung von RAM erhöht werden kann und wir alle wissen, wie teuer RAM ist. GROSSES PROBLEM!! weil ich arm bin! irgendeine Lösung dafür? Kann Sqlite verwendet werden, anstatt den Status im Speicher zu speichern? Mache ich die Sache komplexer, indem ich mehrere Sqlite-Instanzen in meine Anwendung einsetze? 
  4. Längere Startzeit : Bei einem Fehler oder Software-Upgrade ist der Startvorgang je nach Anzahl der Ereignisse langsam. Aber wir können Schnappschüsse verwenden, um das zu lösen?
  5. Eventuelle Konsistenz : Problem bei einigen Anwendungen. Stellen Sie sich vor, Facebook würde Event-Sourcing mit CQRS verwenden, um Beiträge zu speichern und zu überlegen, wie beschäftigt das System von Facebook ist. Wenn ich einen Beitrag gepostet hätte, würde ich am nächsten Tag meinen fb-Beitrag sehen.
  6. Serialisierte Ereignisse im Ereignisspeicher : Bei Ereignisspeichern werden Ereignisse als serialisierte Objekte gespeichert. Dies bedeutet, dass wir den Inhalt von Ereignissen im Ereignisspeicher nicht abfragen können, der sowieso nicht empfohlen wird. In Zukunft können wir dem Ereignis kein weiteres Attribut hinzufügen. Lösung wäre, Ereignisse als JSON-Objekte anstelle von serialisierten Ereignissen zu speichern? Aber ist das eine gute Idee? Oder fügen Sie weitere Ereignisse hinzu, um die Änderung des ursprünglichen Ereignisobjekts zu unterstützen? 

Kann jemand bitte die Nachteile, die ich hier angesprochen habe, kommentieren und mich korrigieren, wenn ich falsch liege, und andere vorschlagen, die ich vielleicht übersehen habe? 

25
hajime

Hier ist meine Meinung dazu.

  1. CQRS + ES kann die Dinge in komplexen Softwaresystemen erheblich vereinfachen, indem umfangreiche Domänenobjekte, einfache Datenmodelle, Verlaufsverfolgung, mehr Transparenz bei Parallelitätsproblemen, Skalierbarkeit und vieles mehr zur Verfügung stehen. Es erfordert jedoch eine andere Art, über die Systeme nachzudenken, so dass es schwierig sein könnte, qualifizierte Entwickler zu finden. Mit CQRS wird es jedoch einfacher, die Verantwortlichkeiten zwischen den Entwicklern zu trennen. Ein Nachwuchsentwickler kann beispielsweise nur mit der Leseseite arbeiten, ohne die Geschäftslogik berühren zu müssen.

  2. Datenkopien erfordern mit Sicherheit mehr Speicherplatz. Aber die Lagerung ist heutzutage relativ günstig. Es kann erforderlich sein, dass das IT-Supportteam weitere Sicherungen durchführt und plant, wie das System wiederhergestellt werden kann, falls Probleme auftreten. Durch die Servervirtualisierung wird der Workflow jedoch heute rationalisiert. Es ist auch viel einfacher, Redundanz im System ohne eine monolithische Datenbank zu erstellen.

  3. Ich sehe höhere Speicherauslastung nicht als Problem an. Die Hydrierung von Geschäftsobjekten sollte auf Anfrage erfolgen. Objekte sollten keine Verweise auf Ereignisse beibehalten, die bereits beibehalten wurden. Die Hydratisierung von Ereignissen sollte nur bei persistierenden Daten erfolgen. Auf der Leseseite gibt es keine Entity-> DTO-> ViewModel-Konvertierungen, die normalerweise in gestuften Systemen vorkommen, und Sie hätten keine Objektänderungsverfolgung, die die voll funktionsfähigen ORMs normalerweise durchführen. Die meisten Systeme führen wesentlich mehr Lesevorgänge aus als Schreibvorgänge.

  4. Eine längere Startzeit kann ein geringfügiges Problem sein, wenn Sie aufgrund der Initialisierung verschiedener Datenkontexte mehrere heterogene Datenbanken verwenden. Wenn Sie jedoch etwas einfaches wie ADO .NET verwenden, um mit dem Ereignisspeicher und einem Mikro-ORM für die Leseseite zu interagieren, wird das System schneller als jeder voll funktionsfähige ORM "kaltstart". Das Wichtigste dabei ist, den Zugriff auf die Daten nicht zu komplizieren. Das ist eigentlich ein Problem, das CQRS lösen soll. Und wie ich schon sagte, sollte die Leseseite für die Ansichten modelliert werden und keinen Overhead für die Neuzuordnung von Daten haben.

  5. Das Zwei-Phasen-Festschreiben kann gut für Systeme funktionieren, die meiner Erfahrung nach nicht für Tausende Benutzer skaliert werden müssen. Sie müssen Datenbanken auswählen, die mit dem Distributed Transaction Coordinator gut funktionieren. PostgreSQL kann beispielsweise gut zum Lesen und Schreiben von separaten Modellen verwendet werden. Wenn das System für eine große Anzahl gleichzeitiger Benutzer skaliert werden muss, muss es unter Berücksichtigung der eventuellen Konsistenz entworfen werden. Es gibt Fälle, in denen Sie Stammwurzeln oder Kontextgrenzen haben, bei denen kein CQRS verwendet wird, um eine eventuelle Konsistenz zu vermeiden. Dies ist für nicht kollaborative Teile der Domäne sinnvoll.

  6. Sie können Ereignisse in einem serialisierten Format wie JSON oder XML abfragen, wenn Sie die richtige Datenbank für den Ereignisspeicher auswählen. Und das sollte nur zu analytischen Zwecken geschehen. Im System darf nichts den Ereignisspeicher nach etwas anderem als der Aggregat-Stamm-ID und dem Ereignistyp abfragen. Diese Daten würden indiziert und leben außerhalb des serialisierten Ereignisses.

28
Dmitry S.

Um nur Punkt 5 zu kommentieren. Mir wurde gesagt, dass Facebook ES mit Eventual Consistency verwendet. Aus diesem Grund kann es vorkommen, dass ein Post nach dem Posten verschwinden und wieder angezeigt wird.

Normalerweise befindet sich das Lesemodell, auf das Ihr Browser zugreift, in Ihrer Nähe, aber nachdem Sie einen Beitrag erstellt haben, wechselt der SPA zu einem Lesemodell, das sich in der Nähe Ihres Schreibmodells befindet. Durch die Nähe zwischen dem Schreibmodell (Ereignissen) und dem Lesemodell sehen Sie Ihren eigenen Beitrag.

15 Minuten später wechselt Ihr SPA jedoch zum ersten näheren Lesemodell. Wenn das Ereignis, das Ihren Beitrag enthält, noch nicht in das Lesemodell übertragen wurde, werden Sie Ihren eigenen Beitrag verschwinden sehen, um später wieder zu erscheinen.

5
Sam Stickland

Ich hoffe, dass ich nicht zu spät komme, um eine Antwort zu geben. In diesen Monaten habe ich mich intensiv mit diesem Thema befasst, um eine Lösung für einige Bereiche meiner Architektur zu implementieren, in denen ES sinnvoll sein kann

Complex: Eigentlich sollte es nicht komplex sein, seine Mission ist es, tödlich einfach zu sein. Wie? Komplexität vom Geschäftslogikcode zum Infrastrukturcode. Der Datenzugriff sollte über Frameworks erfolgen, die noch nicht ausgereift sind. Trotzdem gibt es keinen klaren Sieger im ES/CQRS-Rennen, vielleicht weil es sich immer noch um einen Nischen-/Hipster-Ansatz handelt (?). Einige Teams rollen also ihre eigene Lösung oder übernehmen eine fertige Technologie wie Axon

Hoher Speicherplatzverbrauch: Ich würde mehr sagen, ich würde * potentiell unendlich * Festplattenverbrauch sagen. Aber wenn Sie in Richtung ES gehen, haben Sie auch einen sehr guten Grund, dieses offensichtliche Drwaback zu tolerieren. Geben wir einige davon:

  1. Audit Logs: Der Datenspeicher ist ein Ereignisprotokoll, wir wissen es bereits. Finanz-Apps oder jede Mission/Sicherheitskritik benötigen möglicherweise ein zentrales Audit-Protokoll, mit dem Wer erstellt Was in Welcher Moment Angegeben werden kann =. ES bietet diese Funktion der Box ... Sie können Ihre Ereigniseinträge auch mit einigen geschäftsbedrohlichen Metadaten dekorieren (z. B. einer Transaktions-ID, die mit einer API-Verbraucheridentität korreliert ist, einem Schweregrad des Vorgangs ...).

  2. High Concurrency: Es gibt Systeme, in denen logische Ressourcenzustände von vielen Clients gleichzeitig geändert werden. Dies sind Spiele, IoT-Plattformen und so weiter. Das Protokollieren von Ereignissen anstelle des Änderns einer Statusdarstellung kann eine intelligente Methode sein, um eine Gesamtreihenfolge von Ereignissen bereitzustellen. Die andere Möglichkeit besteht darin, das Synchronisierungsmaterial an die Datenbank zu delegieren. Aber das ist nicht das, was Sie wollen, wenn Sie in ES sind

  3. Analytics Nehmen wir an, Sie haben viele Daten mit viel Geschäftswert, aber Sie wissen immer noch nicht, welche. Seit Jahren extrahieren wir Wissen aus Anwendungsinformationen, indem wir die Datenorganisation mit verschiedenen Informationsmodellen (OLAP-Cubes) übersetzen. Der Event Store bietet wieder etwas Ähnliches. Ereignisprotokoll ist die einfachste Form der Darstellung von Informationen. Sie haben viele Möglichkeiten, sie im Stapel zu verarbeiten oder auf gespeicherte Ereignisse zu reagieren

Hohe Speichernutzung: Ich denke, es sollte dasselbe sein, wenn Sie Ihre Projektion erstellt haben

Längere Startzeit: Wenn die Leseseite ihre Projektionen zwischenspeichert und das letzte Aktualisierungsereignis "merkt", sollte nicht die gesamte Ereignissequenz erneut angewendet werden. Schnappschüsse sind eine Minderung, aber wenn Sie viele Schnappschüsse machen, haben Sie vielleicht mit ES eine schlechte Wahl getroffen. Ich denke, dass dieses Problem in Microservices-Ökosystemen, in denen die Startzeit ohne Betriebsunterbrechung maskiert werden kann, gering ist. Tatsächlich holen Sie das Beste aus ES/CQRS heraus, wenn Sie es so auf Microservices anwenden

Eventuelle Konsistenz: Schuld daran ist der CAP-Satz, nicht ES. Viele Nicht-ES/CQRS müssen sich damit auseinandersetzen, aber es gibt viele Szenarien, in denen dies kein wirkliches Problem darstellt. Dies sind die scnearios, in denen ES gut passt. Sie können ES- und Nicht-ES-Dienste auf derselben Plattform kombinieren

Serialisierte Ereignisse im Ereignisspeicher: Wenn es wichtig ist, eine nicht serialisierte Ereignisdarstellung zu haben, können Sie eine dokumentorientierte Datenbank verwenden. Wenn Sie dies jedoch tun, um Abfragen über die Nutzlast von Ereignissen durchzuführen, fehlt Ihnen der Punkt von ES/CQRS. ES bedeutet, alle Datenmanipulationen von der DB-Seite auf die Anwendungsebene zu verlagern, wo sich jedes Teil schnell ändert und alles zustandslos ist. Dies verbessert die Skalierbarkeit und Fehlertoleranz und bietet die Möglichkeit, die Organisation Ihres Teams zu gestalten, indem Sie beispielsweise dem Frontend-Mann/der Frontend-Frau die Möglichkeit geben, seine/ihre BFF einfach in Javascript zu schreiben.

Ich hoffe, diese Grundsätze mit gutem Ergebnis in die Praxis umzusetzen und die Vorteile dieses aufregenden Ansatzes zu nutzen

1
Carmine Ingaldi

Ich weiß, dass diese Frage fast 3 Jahre her ist, aber dieser Artikel kann für jemanden nützlich sein. Schlüsselpunkte sind

  • Skalieren mit Momentaufnahmen
  • Sichtbarkeit der Daten
  • Schema ändern
  • Umgang mit komplexen Domains
  • Müssen Sie es den meisten neuen Teammitgliedern erklären
0
kagetoki

Event-Sourcing und CQRS sind großartig, da Entwickler vor einer modellierten Datenbank bleiben müssen, mit der der Entwickler während der gesamten Lebensdauer der Anwendung arbeiten muss, es sei denn, es gibt ein Big Data-Migrationsprojekt.

Dies ist ein großes Missverständnis. Die relationalen Datenbanken wurden genau für die Entwicklung des Modells erfunden (dank einfacher zweidimensionaler Tabellen im Gegensatz zu vordefinierten hierarchischen Strukturen). Durch Ansichten und Prozeduren, die die Kapselung des Datenzugriffs sicherstellen, können sich das logische und physische Modell unabhängig voneinander entwickeln. Aus diesem Grund definiert SQL auch DDL und DML in derselben Sprache. In einigen RDBMS können auch all diese Entwicklungen versioniert und online (Continuous Delivery) als Oracle Edition-basierte Neudefinition bereitgestellt werden. 

Große Datenstrukturen sind vordefiniert und können nur mit dem für diese Struktur entwickelten Code gelesen werden. Ok, wenn Sie sofort verbraucht werden, aber es wird Ihnen schwer fallen, es 10 Jahre später ohne die genaue Version und den Sprachcompiler oder -interpreter zu lesen.

0
FranckPachot