Ich gehe durch die Forschungsphase für ein neues Projekt und diskutiere gerade mit einem Arbeitskollegen über die Architektur des Projekts.
Wir haben vereinbart, dass wir ein verteiltes Nachrichtensystem mit CQRS und Event Sourcing mit azure erstellen werden. Es wird ein SPA mit dem Frontend mit eckigen js sein und das Backend wird Web API sein.
Wir haben jetzt besprochen, wie die Datenbank eingerichtet wird und wo die Unterschiede aufgetreten sind.
Wir haben vereinbart, dass wir die Datenbank in zwei Datenbanken aufteilen werden, eine für das Lesen und Schreiben. Mein Arbeitskollege möchte sql server sowohl für die Lese- als auch für die Schreib-Datenbank nutzen, da er seine ganze Karriere in sql verbracht hat und nichts anderes als sql hören möchte. Ich andererseits habe über NoSql geforscht und ich denke, dass es für die gelesene Datenbank passend sein würde, da es für Leistung besser ist.
Da es bei CQRS immer um Konsistenz geht, habe ich gelesen, dass auch NoSql-Datenbanken darauf basieren, was mich nun dazu bringt, NoSql auch für die Write-Datenbank zu verwenden.
Wir wollten auch eine Ereignistabelle für jedes Aggregatstammverzeichnis anstelle einer generischen Ereignistabelle erstellen, die alle Ereignisse enthält. Da diese Tabellen nicht relational sind, dachte ich, warum wir sql server verwenden sollten.
Meine Fragen sind eher eine Best Practice oder eine allgemeine Herangehensweise an die Art und Weise, wie Menschen ihre Event Stores erstellen.
Die letzte Frage ist in erster Linie meinungsbezogen, also lassen Sie die ersten zwei Fragen aus meiner Sicht beantworten.
Bevor ich das tue, möchte ich sagen, dass wir einen SQL Server (Postgres) für unseren Event Store verwenden. Mit CQRS + ES ist es trivial, einen primären Master für die Schreibvorgänge in der Datenbank zu haben, das Repository von den Slaves lesen zu lassen (nicht zu verwechseln mit den CQRS-Lesevorgängen). Skalierbarkeit sollte in diesem Setup kein Problem sein (wenn Reddit skalieren mit Postgres in Master / Slave, also können Sie).
Ich habe die verschiedenen Optionen für NoSQL-Stores ausführlich evaluiert. Am Ende des Tages konnte ich für ein CQRS + ES-Setup keine Vorteile gegenüber dem SQL-Ansatz im Master / Slave-Modus finden, der, IMO, die Nachteile einer NoSQL-Datenbank überwiegen würde.
Es ist insbesondere trivial, optimistisches Sperren in einem SQL-Speicher zu implementieren (eindeutige Einschränkung für streamId- und versionsfelder), aber es ist ziemlich schwierig (unmöglich?), eine zuverlässige optimistische Sperrung in einfachen NoSQL-Schlüsselwertspeichern zu erreichen.
Bei einigen Dokumentenspeichern ist es möglich (ich denke, es gibt einen Grund, warum NEventStore unterstützt wird nur RavenDB und MongoDB.):
In Postgres verwende ich eine einzige Ereignistabelle für alle Ereignisse.
Was die zweite Frage anbelangt, denke ich, dass Sie zwischen dem Ereignisspeicher und dem Lesemodell unterscheiden müssen. Wir verwenden einen SQL-Server für den Ereignisspeicher (aus den oben genannten Gründen), aber für das CQRS Lesemodell finde ich NoSQL- "Datenbanken" sehr gut geeignet, da der mögliche Konsistenzansatz sehr gut passt mit dem NoSQL-Paradigma. Außerdem fragt man die Leseseite normalerweise nur nach Schlüssel ab, so dass Sie jeden beliebigen Schlüssel / Wert-Speicher verwenden können, der Ihren Anforderungen entspricht. Wir verwenden nicht einmal eine Datenbank, sondern ein In-Memory-Grid, das bei Bedarf neu erstellt wird.
Persönlich bevorzuge ich ein Aggregat pro Tabelle, aber das hängt von Fall zu Fall ab. Selbst wenn eine Tabelle für alle Aggregate verwendet wird, kann partition tech verwendet werden, um potenzielle Leistungsprobleme zu mindern.
Ich denke, NoSQL ist sowohl für die Lese- als auch für die Schreibseite machbar, aber die SQL-Datenbank bietet ein praktisches Feature: Transactionality. Dies ist besonders nützlich, wenn Sie mehrere Ereignisse in einer Transaktion festschreiben müssen. Für die NoSQL-Datenbank müssen Sie möglicherweise Ihr Schema ändern, um dies zu erreichen. Zum Beispiel die Verwendung pro Transaktion bei der Übernahme von Mongo. Oder Sie könnten Cassandra verwenden und jede Zeile als ein Aggregat (ein Ereignis pro Spalte, Cassandra bietet teilweise Transaktionalität für Zeilenebene) machen.
Aber das ist kein großer Vorteil, wenn Ihr Programm nur ein Ereignis pro Transaktion veröffentlicht oder Konsistenz keine starke Anforderung ist.
Nur weil Sie nicht FK (Beziehungen) verwenden, ist SQL ein "Overkill" für Event Sourcing. FKs sind nicht zwingend in SQL.
NoSQL ist ein cooles Konzept, aber in meiner persönlichen Erfahrung habe ich die Arbeit mit SQL viel einfacher in allen Aspekten gefunden.
Überlege es nicht zu sehr. Verwenden Sie SQL. Lass deinen Mitarbeiter alleine :) (Scherz) und mach die Arbeit fertig. Am Ende des Tages sind die meisten unserer "Kopfschmerzen" unsere Unfähigkeit, die Versuchungen neuer Technologien / Erfahrungen dort draußen zu blockieren.
Macht es Sinn?
Tags und Links nosql event-sourcing event-store cqrs