CQRS Datenspeicher Ansatz Nosql oder Sql Server

8

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.

  1. Verwenden Sie eine Tabelle für alle Ereignisse oder erstellen Sie eine Ereignistabelle pro Gesamtstammverzeichnis?
  2. Was wären die Vor- und Nachteile der Verwendung einer NoSql-Datenbank für die Schreib- und Lese-Datenbanken für eine CQRS-Anwendung?
  3. Wie würden Sie schließlich einen hartnäckigen Arbeitskollegen, der mit Sql verheiratet ist, dazu überreden, sich in einen NoSql-Ansatz zu verwandeln?
user3177251 26.07.2014, 19:15
quelle

3 Antworten

7

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.):

  1. RavenDB unterstützt die Transaktion mit ACID, aber Sie müssen .NET verwenden / bereitstellen, was für einige (einschließlich uns) keine Option ist.
  2. MongoDB hat serverseitige atomare Operationen, die Sie brauchen Ereignisse an den Ereignisstrom anhängen UND die Version stoßen Nummer in einer atomaren Operation, aber es gibt einige technische Einschränkungen (insbesondere die maximale Dokumentgröße), die mich von MongoDB als Ereignisspeicher. Außerdem habe ich diesen Artikel zu InfoQ gelesen Partitionstoleranz, und Postgres schien viel mehr zu sein zuverlässig als 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.

    
Alexander Langer 27.07.2014 09:30
quelle
4

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.

    
Hippoom 28.07.2014 02:24
quelle
2

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?

    
Pepito Fernandez 06.01.2017 17:18
quelle