Wie gehen Sie mit dem Rätsel um, die Datenbank aufzubrechen, wenn Sie monolithische Anwendungen in Microservices aufteilen? Typische Anwendungen, an denen ich gearbeitet habe, führen aus Gründen der Leistung und Einfachheit viele Datenbankintegrationen durch.
Wenn Sie zwei Tabellen haben, die logisch unterschiedlich sind (wenn Sie so wollen, begrenzte Kontexte), aber häufig eine aggregierte Verarbeitung für ein großes Datenvolumen durchführen, vermeiden Sie im Monolithen höchstwahrscheinlich die Objektorientierung und verwenden stattdessen den Standard Ihrer Datenbank JOIN-Funktion zum Verarbeiten der Daten in der Datenbank, bevor die aggregierte Ansicht an Ihre App-Ebene zurückgegeben wird.
Wie rechtfertigen Sie die Aufteilung solcher Daten in Microservices, bei denen Sie vermutlich die Daten über eine API und nicht über die Datenbank "verbinden" müssen?
Ich habe Sam Newmans Microservices-Buch gelesen und im Kapitel über die Aufteilung des Monolithen gibt er ein Beispiel für "Aufbrechen von Fremdschlüsselbeziehungen", in dem er anerkennt, dass ein Join über eine API langsamer sein wird - aber er fährt fort, wenn Ihre Bewerbung ist sowieso schnell genug. Ist es wichtig, dass sie langsamer als zuvor ist?
Das scheint ein bisschen glib? Was sind die Erfahrungen der Menschen? Mit welchen Techniken haben Sie die API-Verknüpfungen akzeptabel gemacht?
quelle
Antworten:
Wenn Leistung oder Latenz keine große Rolle spielen (ja, wir brauchen sie nicht immer), ist es vollkommen in Ordnung, nur einfache RESTful-APIs zum Abfragen zusätzlicher Daten zu verwenden, die Sie benötigen. Wenn Sie mehrere Aufrufe an verschiedene Microservices ausführen und ein Ergebnis zurückgeben müssen, können Sie das API-Gateway- Muster verwenden.
Redundanz in Polyglot-Persistenzumgebungen ist vollkommen in Ordnung . Beispielsweise können Sie die Messaging-Warteschlange für Ihre Microservices verwenden und jedes Mal "Update" -Ereignisse senden, wenn Sie etwas ändern. Andere Microservices hören die erforderlichen Ereignisse ab und speichern Daten lokal. Anstatt abzufragen, speichern Sie alle erforderlichen Daten in einem geeigneten Speicher für einen bestimmten Microservice.
Vergessen Sie auch nicht das Caching :) Sie können Tools wie Redis oder Memcached verwenden , um zu vermeiden, dass andere Datenbanken zu oft abgefragt werden .
quelle
Es ist in Ordnung, dass Dienste schreibgeschützte replizierte Kopien bestimmter Referenzdaten von anderen Diensten haben.
Wenn ich versuche, eine monolithische Datenbank in Microservices umzugestalten (im Gegensatz zum Umschreiben), würde ich dies tun
Auf diese Weise können Sie Tabellendaten / Strukturen unabhängig voneinander ändern, ohne andere Anwendungen zu beschädigen.
Anstatt Ansichten zu verwenden, könnte ich auch Trigger verwenden, um Daten von einem Schema in ein anderes zu replizieren.
Dies wäre ein schrittweiser Fortschritt in die richtige Richtung, der die Nähte Ihrer Komponenten festlegt, und ein Wechsel zu REST kann später erfolgen.
* Die Ansichten können erweitert werden. Wenn eine wichtige Änderung erforderlich ist, erstellen Sie eine Version 2 derselben Ansicht und entfernen Sie die alte Version, wenn sie nicht mehr benötigt wird. ** oder Tabellenwertfunktionen oder Sprocs.
quelle
CQRS --- Command Query Aggregation Pattern ist die Antwort auf diese Frage gemäß Chris Richardson. Lassen Sie jeden Microservice sein eigenes Datenmodell aktualisieren und generieren Sie die Ereignisse, die die materialisierte Ansicht mit den erforderlichen Join-Daten von früheren Microservices aktualisieren. Dieses MV kann eine beliebige NoSql-Datenbank oder Redis oder Elasticsearch sein, die abfrageoptimiert ist. Diese Technik führt zu einer eventuellen Konsistenz, die definitiv nicht schlecht ist und die anwendungsseitigen Verknüpfungen in Echtzeit vermeidet. Hoffe das antwortet.
quelle
Ich würde die Lösungen für den Einsatzbereich trennen, beispielsweise für Betrieb und Berichterstattung.
Für die Microservices, die Daten für einzelne Formulare bereitstellen, die Daten von anderen Microservices benötigen (dies ist der Betriebsfall), ist die Verwendung von API-Joins meiner Meinung nach der richtige Weg. Sie werden keine großen Datenmengen benötigen, sondern können die Daten in den Dienst integrieren.
Der andere Fall ist, wenn Sie große Abfragen für große Datenmengen durchführen müssen, um Aggregationen usw. durchzuführen (der Berichtsfall). Für diesen Bedarf würde ich darüber nachdenken, eine gemeinsam genutzte Datenbank zu verwalten - ähnlich wie bei Ihrem ursprünglichen Schema - und sie mit Ereignissen aus Ihren Microservice-Datenbanken zu aktualisieren. In dieser gemeinsam genutzten Datenbank können Sie weiterhin Ihre gespeicherten Prozeduren verwenden, was Ihren Aufwand spart und die Datenbankoptimierungen unterstützt.
quelle
In Microservices erstellen Sie diff. Lesen Sie Modelle, also zum Beispiel: wenn Sie zwei Diff haben. Begrenzter Kontext und jemand möchte nach beiden Daten suchen, dann muss jemand Ereignisse aus beiden begrenzten Kontexten abhören und eine für die Anwendung spezifische Ansicht erstellen.
In diesem Fall wird mehr Speicherplatz benötigt, es werden jedoch keine Verknüpfungen und keine Verknüpfungen benötigt.
quelle