Ist es eine schlechte Praxis für Dienste, eine Datenbank in SOA freizugeben?

17

Ich habe kürzlich Hohpes und Woolfs Enterprise Integration Patterns gelesen, einige von Thomas Erl's Büchern über SOA und mir verschiedene Videos und Podcasts von Udi Dahan et al. zu CQRS- und ereignisgesteuerten Systemen.

Systeme an meinem Arbeitsplatz leiden unter hoher Kopplung. Obwohl theoretisch jedes System eine eigene Datenbank hat, gibt es viele Verknüpfungen zwischen ihnen. In der Praxis bedeutet dies, dass alle Systeme eine riesige Datenbank verwenden. Beispielsweise gibt es eine Tabelle mit Kundendaten.

Vieles von dem, was ich gelesen habe, scheint darauf hinzudeuten, Daten zu denormalisieren, sodass jedes System nur seine Datenbank verwendet und alle Aktualisierungen an einem System über Messaging an alle anderen übertragen werden.

Ich dachte, dies sei eine der Möglichkeiten, die Grenzen in SOA durchzusetzen - jeder Dienst sollte eine eigene Datenbank haben, aber dann las ich Folgendes:

/programming/4019902/soa-joining-data-across-multiple-services

und es deutet darauf hin, dass dies das Falsche ist.

Die Trennung der Datenbanken scheint ein guter Weg zu sein, um Systeme zu entkoppeln, aber jetzt bin ich ein bisschen verwirrt. Ist das ein guter Weg? Wird jemals empfohlen, eine Datenbank nach einem SOA-Dienst, einem DDD-gebundenen Kontext, einer Anwendung usw. zu trennen?

Paul T Davies
quelle
Die ursprüngliche Frage, die Sie verlinken, ist falsch. Die Frage selbst ist falsch, da die meisten Antworten nicht beantwortet werden können. Bei SOA geht es nicht darum, eine einzelne Anwendung in einzelne Dienste aufzuteilen und deren Daten zu partitionieren.
Jeremy
Ich verstehe, dass die Frage falsch ist. Es waren die Antworten, die mich dazu gebracht haben, mein Denken neu zu überdenken.
Paul T Davies
Ich denke, die Dienste müssen gekoppelt werden
B Seven

Antworten:

12

Die Entkopplung funktioniert nur, wenn wirklich eine Trennung vorliegt. Überlegen Sie, ob Sie ein Bestellsystem haben:

  • Tisch: KUNDE
  • Tabelle: BESTELLUNG

Wenn das alles ist, gibt es keinen Grund, sie zu entkoppeln. Auf der anderen Seite, wenn Sie dies haben:

  • Tisch: KUNDE
  • Tabelle: BESTELLUNG
  • Tabelle: CUSTOMER_NEWSLETTER

Dann könnte man argumentieren, dass ORDER und CUSTOMER_NEWSLETTER Teil von zwei völlig getrennten Modulen sind (Bestellung und Marketing). Möglicherweise ist es sinnvoll, diese in separate Datenbanken zu verschieben (eine für jede Tabelle) und beide Module gemeinsam auf die gemeinsame Tabelle CUSTOMER in ihrer eigenen Datenbank zuzugreifen.

Auf diese Weise vereinfachen Sie jedes Modul, erhöhen jedoch die Komplexität Ihrer Datenschicht. Da Ihre Anwendung immer größer wird, sehe ich einen Vorteil für die Trennung. Es wird immer mehr "Dateninseln" geben, die wirklich keine Beziehung zueinander haben. Es werden jedoch immer einige Daten vorhanden sein, die alle Module überschneiden.

Die Entscheidung, sie in verschiedene physische Datenbanken zu stellen, basiert normalerweise auf realen Einschränkungen wie der Häufigkeit von Sicherungen, Sicherheitseinschränkungen, der Replikation an verschiedenen geografischen Standorten usw. Ich würde Tabellen nicht einfach aus Gründen der Trennung in verschiedene physische Datenbanken aufteilen. Dies kann mit verschiedenen Schemata oder Ansichten einfacher gehandhabt werden.

Scott Whitlock
quelle
5
-1. Sie sollten sich nur in separaten Datenbanken befinden, wenn es einen Grund gibt, sie dort abzulegen. Sie müssen "etwas rausholen", da dies Ihre App sicherlich komplexer macht.
Scottschulthess
1
Ich denke, es lohnt sich, die Bedeutung der Trennung der beiden Funktionsbereiche auf der Datenebene herauszustellen (unabhängig davon, ob separate Schemas oder etwas anderes verwendet werden). Jedes Modul sollte nur über die API des anderen Moduls auf die Daten des anderen Moduls zugreifen - dies ähnelt den OO-Kapselungsprinzipien. Das heißt, ein Schema wird nicht zwischen mehreren Modulen geteilt. Auch würde ich gegen Ansichten empfehlen, stattdessen lieber Daten über offenzulegen. eine API.
Chris Snow
@scottschulthess ja, du musst die Komplexitätskosten abwägen und wenn es sich nicht lohnt, kannst du es einfach nicht in Services aufteilen. Das Aufteilen, aber die Verwendung einer gemeinsam genutzten Datenbank, die ich gefunden habe, ist die schlechteste der drei Optionen.
Adamantish
8

Wo ich arbeite, haben wir einen ESBmit denen 6 verschiedene anwendungen (oder sollte ich sagen "endpunkte") verbunden sind. Diese 6 Anwendungen arbeiten mit 3 verschiedenen Oracle-Schemas auf 2 Datenbankinstanzen. Einige dieser Anwendungen existieren im selben Schema, nicht weil sie verwandt sind, sondern weil unsere Datenbankinfrastruktur von einem externen Anbieter verwaltet wird und das Abrufen eines neuen Schemas nur für immer dauert (wir haben natürlich auch keinen DBA-Zugriff) Es dauert wirklich so lange, bis wir "vorübergehend" daran gedacht haben, ein vorhandenes Schema wiederzuverwenden, um die Entwicklung fortsetzen zu können. Um die "Trennung" von Daten zu erzwingen, werden Tabellennamen vorangestellt, z. B. "CST_" für den Kunden. Außerdem müssen wir mit einem Schema arbeiten, das wir aus triftigen Gründen nicht absolut ändern können ... Es ist seltsam, ich weiß. Natürlich, wie es immer passiert, "vorübergehend"

Unsere verschiedenen Anwendungen stellen eine Verbindung zu ihrem jeweiligen Datenbankschema her und arbeiten mit ihren eigenen PL / SQL-Paketen. Es ist uns absolut untersagt, direkt mit Tabellen / Daten zu interagieren, die sich außerhalb unserer Anwendungsdomäne befinden.

Wenn eine der mit dem ESB verbundenen Anwendungen Informationen außerhalb ihrer Domäne benötigt, ruft sie den zugehörigen Dienst auf dem ESB auf, um die Daten abzurufen, auch wenn diese Informationen tatsächlich im selben Schema vorliegen und theoretisch nur eine kleine Join-Anweisung erforderlich ist eine der SQL-Anforderungen .

Wir tun dies, um unsere Anwendungsdomäne in verschiedene Schemas / Datenbanken aufteilen zu können und um sicherzustellen, dass die Dienste auf dem ESB in diesem Fall weiterhin ordnungsgemäß funktionieren (es ist Weihnachten, wir schnüren uns die Finger).

Nun, von außen mag das seltsam und schrecklich aussehen, aber es gibt Gründe dafür, und ich wollte nur diese konkrete Erfahrung teilen, um Ihnen zu zeigen, dass eine oder mehrere Datenbanken nicht so wichtig sind. Warten Sie, es ist! Aus vielen Gründen (+1 für Scott Whitlock, siehe letzter Absatz über Backup und so, dass Sie in Schwierigkeiten geraten). Aber es ist genauso wichtig, dass Ihre SOA-Services richtig entworfen werden, zumindest ist dies meine Meinung und ich bin kein DBA. Letztendlich gehören alle Ihre Datenbanken zu Ihrem "Enterprise Data Warehouse", oder?

Schließlich werde ich den letzten Absatz von Scott Whitlock nicht umformulieren, insbesondere diesbezüglich

Ich würde Tabellen nicht einfach aus Gründen der Trennung von Bedenken in verschiedene physische Datenbanken aufteilen.

ist wirklich super wichtig. Tu es nicht, wenn es keinen Grund gibt.

Jalayn
quelle
8

Ich habe die schlimmsten Alpträume in der Software-Architektur aufgrund der Datenintegration gesehen und die beste Waffe gegen diese Art von Chaos, die ich bisher in DDD-artigen beschränkten Kontexten erlebt habe. Was in gewissem Sinne nicht weit von "SOA richtig gemacht" entfernt ist.

Daten selbst sind jedoch nicht der beste Weg, um das Problem anzugehen. Man sollte sich auf das erwartete / benötigte Verhalten konzentrieren und die Daten dahin bringen, wo es darauf ankommt. Auf diese Weise könnte es zu einer gewissen Verdoppelung kommen, aber dies ist normalerweise kein Problem im Vergleich zu den Systementwicklungsblöcken, die fast immer mit datenintegrierten Architekturen verbunden sind.

Einfach ausgedrückt: Wenn Sie nach lose gekoppelten Systemen suchen, bleiben Sie nicht an die Daten gekoppelt. Entscheiden Sie sich für rollengekapselte Systeme und einen gut strukturierten Kommunikationskanal dazwischen, der als " Verkehrssprache " fungiert.

ZioBrando
quelle
1
Und ... direkt auf die Titelfrage antworten: "Ja, ich würde es als riskante Praxis betrachten, eine Datenbank in einer SOA freizugeben."
ZioBrando
7

Das Entkoppeln von Datenbanken und die Konsistenz der Daten untereinander ist eine Aufgabe auf Expertenebene. Es ist sehr leicht, Fehler zu machen und Probleme mit Duplikaten usw. zu bekommen, die mit dem aktuellen System vermieden werden sollen. Um ehrlich zu sein, ein funktionierendes System zu übernehmen und dies zu tun, ist so ziemlich die Garantie dafür, dass neue Bugs eingeführt werden, die für die Benutzer keinen echten Wert haben.

HLGEM
quelle
1

Wenn es richtig gemacht wird, ist es eine Tugend , die geschäftlichen Belange in verschiedene Datenbanken (oder zumindest in verschiedene Schemata) zu unterteilen .

Bitte lesen Sie Martin Fowlers Beschreibung des CQRS-Musters :

Da unsere Anforderungen immer komplexer werden, entfernen wir uns stetig von [ein Informationssystem wie einen CRUD-Datenspeicher behandeln] ... Die Änderung, die CQRS einführt, besteht darin, dieses konzeptionelle Modell in separate Modelle für die Aktualisierung und Anzeige aufzuteilen ... Es gibt Raum für erhebliche Variationen Hier. Die speicherinternen Modelle können dieselbe Datenbank gemeinsam nutzen. In diesem Fall fungiert die Datenbank als Kommunikation zwischen den beiden Modellen. Sie können jedoch auch separate Datenbanken verwenden , wodurch die Datenbank der Abfrageseite effektiv durch eine Echtzeit-ReportingDatabase erstellt wird. In diesem Fall muss es einen Kommunikationsmechanismus zwischen den beiden Modellen oder ihren Datenbanken geben.

Und NServiceBus-Architekturprinzipien :

Befehlsabfragetrennung

Eine Lösung, die dieses Problem vermeidet, trennt Befehle und Abfragen auf Systemebene, auch über die von Client und Server hinaus. In dieser Lösung gibt es zwei "Dienste", die sich sowohl auf den Client als auch auf den Server erstrecken - einen für Befehle (Erstellen, Aktualisieren, Löschen) und einen für Abfragen (Lesen). Diese Dienste kommunizieren nur über Nachrichten - einer kann nicht auf die Datenbank des anderen zugreifen ...

Und Command and Query Responsibility Segregation (CQRS)

Befehls- und Abfrageverantwortungstrennung

Die meisten Anwendungen lesen Daten häufiger als sie Daten schreiben. Basierend auf dieser Aussage wäre es eine gute Idee, eine Lösung zu finden, bei der Sie einfach weitere Datenbanken hinzufügen können, aus denen Sie lesen können, oder? Was ist, wenn wir eine Datenbank nur zum Lesen einrichten? Noch besser; Was ist, wenn wir die Datenbank so gestalten, dass sie schneller gelesen werden kann? Wenn Sie Ihre Anwendungen auf der Grundlage der in der CQRS-Architektur beschriebenen Muster entwerfen, erhalten Sie eine Lösung, die skalierbar und schnell beim Lesen von Daten ist.

Jim G.
quelle