it-swarm.com.de

Microservices und Datenspeicherung

Ich denke darüber nach, eine monolithische REST API) in eine Microservice-Architektur zu verschieben, und bin etwas verwirrt über die Datenspeicherung. Aus meiner Sicht sind einige der Vorteile von Microservices:

  • Horizontal skalierbar - Ich kann mehrere redundante Kopien eines Mikrodienstes ausführen, um die Last und/oder den Ausfall eines Servers zu bewältigen.
  • Locker gekoppelt - Ich kann interne Implementierungen von Microservices ändern, ohne die anderen ändern zu müssen, und ich kann sie unabhängig bereitstellen und ändern usw.

Mein Problem ist die Datenspeicherung. Aus meiner Sicht gibt es mehrere Möglichkeiten:

  1. Ein einziger Datenbankdienst, der von allen Mikrodiensten gemeinsam genutzt wird - dies scheint den Vorteil einer losen Kopplung vollständig auszuschließen.
  2. Eine lokal installierte Datenbankinstanz auf jedem Microservice - Ich sehe keine Möglichkeit, dies horizontal zu skalieren, daher denke ich nicht, dass dies eine Option wäre.
  3. Jeder Mikrodienst verfügt über einen eigenen Datenbankdienst - dies scheint der vielversprechendste zu sein, da die Vorteile einer losen Kopplung und horizontalen Skalierung (Verwendung redundanter Datenbankkopien und/oder Sharding über mehrere) erhalten bleiben.

Für mich scheint die dritte Option die einzige Option zu sein, aber sie scheint mir unglaublich schwer und eine sehr überentwickelte Lösung zu sein. Wenn ich es richtig verstehe, müsste ich für eine einfache Anwendung mit 4-5 Microservices 16-20 Server ausführen - zwei tatsächliche Microservice-Instanzen pro Microservice (im Falle eines Serverausfalls und für die Bereitstellung ohne Ausfallzeit) und zwei Datenbankdienstinstanzen pro Mikrodienst (bei Serverausfall usw.).

Dies scheint, ganz offen gesagt, etwas lächerlich. 16-20 Server, um eine einfache API auszuführen, wenn man bedenkt, dass ein realistisches Projekt wahrscheinlich mehr als 4-5 Dienste haben wird? Gibt es ein grundlegendes Konzept, das mir fehlt, um dies zu erklären?

Einige Dinge, die bei der Beantwortung helfen können:

  • Ich bin der einzige Entwickler für dieses Projekt und werde es auf absehbare Zeit sein.
  • Ich verwende Node.js und MongoDB, aber ich würde mich für sprachunabhängige Antworten interessieren - eine Antwort könnte sogar sein, dass ich nur die falschen Technologien verwende!
27
penalosa

Von Ihren drei Optionen sind die erste (eine einzelne, gemeinsam genutzte Datenbank) und die dritte (ein "Datenbankdienst") am häufigsten.

Die erste heißt Integrationsdatenbank . Dies wird im Allgemeinen nicht als gute Lösung in einer Microservice-Architektur angesehen. Es fügt Ihren Diensten eine Kopplung hinzu. Außerdem ist es für einen Dienst sehr einfach, die anderen Dienste einfach zu umgehen und direkt in eine Datenbank abzufragen. Sie können jede Art von Datenintegrität oder -validierung verlieren, die von der Anwendungsebene bereitgestellt wird und nicht auf Datenbankebene erzwungen wird.

Ihre dritte Idee heißt Anwendungsdatenbank . Und Sie haben Recht - es ermöglicht Ihnen, die lose Kopplung auf API-Ebene zwischen Diensten zu erzwingen und Dienste auf Datenbankebene einfacher zu skalieren. Es macht es auch einfacher, die zugrunde liegende Datenbanktechnologie durch eine für jeden Dienst geeignete zu ersetzen, ebenso wie Sie die Technologie oder andere Implementierungsdetails jedes Dienstes ändern können. Sehr flexibel.

Ich würde jedoch eine Zwischenlösung vorschlagen.

Anstatt für jeden Mikrodienst einen Datenbankdienst einzurichten, sollten Sie für jeden Dienst ein Schema erstellen. Wenn Sie mehrere Datenbanktechnologien verwenden, müssen Sie möglicherweise etwas anders aufteilen. Die Idee wäre jedoch, die Anzahl der von Ihnen ausgeführten Datenbankserver zu minimieren, es jedoch sehr einfach zu machen, einen Dienst in einen eigenen Datenbankserver aufzuteilen, wenn und wenn es notwendig wird. Solange Sie einer Datenbank nur den Zugriff auf ihr eigenes Schema erlauben, haben Sie die Vorteile einer Anwendungsdatenbank, jedoch ohne den Overhead von Datenbankservern, die für jede Anwendung oder jeden Dienst vorhanden sind.

Als Einzelentwickler würde ich jedoch zu diesem Zeitpunkt den gesamten Begriff der Mikrodienste in Frage stellen - Martin Fowler schreibt über den Monolith First und den Microservice Premium , spricht Simon Brown über modulare Monolithen und DHH spricht über Majestic Monolith . Ich bin mir nicht sicher, wie gut Ihr Monolith organisiert ist, aber überarbeite und organisiere ihn. Identifizieren Sie Komponenten und trennen Sie sie sauber voneinander, um Teile einfach in einen Service zu extrahieren. Gleiches gilt für Ihre Datenbankstruktur. Konzentrieren Sie sich auf eine gute, saubere und komponentenbasierte Architektur, die das Refactoring in Services unterstützen kann. Microservices verursachen einen hohen Aufwand für einen einzelnen Entwickler, der im Betrieb erstellt und unterstützt werden muss. Wenn Sie jedoch tatsächlich einen Teil des Systems skalieren müssen, verwenden Sie Ihre Überwachungs- und Berichtssysteme, um die Engpässe zu identifizieren, zu einem Service zu extrahieren und nach Bedarf zu skalieren.

22
Thomas Owens

Jeder Mikrodienst verfügt über einen eigenen Datenbankdienst - dies scheint der vielversprechendste zu sein, da die Vorteile einer losen Kopplung und horizontalen Skalierung (Verwendung redundanter Datenbankkopien und/oder Sharding über mehrere) erhalten bleiben.

Zustimmen. Die dritte Option ist die natürliche Wahl für Mikrodienste. Wenn der Mikrodienst wirklich unabhängig sein soll (und nicht Teil eines verteilter Monolith ), ist es normal, dass jeder über eine Datenbank verfügt.

[...] zwei tatsächliche Microservice-Instanzen pro Microservice (bei Serverausfall und für die Bereitstellung ohne Ausfallzeit) und zwei Datenbankdienstinstanzen pro Microservice (bei Serverausfall usw.).

Sie haben Recht mit der Anzahl der ausgeführten Mikrodienste, wenn Sie einen Lastausgleich wünschen. Wenn Sie 4 Mikrodienste planen, müssen Sie mindestens 2 Instanzen jedes Mikrodienstes vorbereiten (insgesamt 8), wie Sie bereits erläutert haben.

Aber zwei Datenbanken pro Mikrodienst? Das ist wirklich fraglich. Ich kenne die Details zu dem Geschäftsproblem, an dem Ihre Mikrodienste teilnehmen werden, nicht, aber eine Datenbankredundanz ist für die meisten Produkte/Projekte ziemlich viel. Ich werde empfehlen, mit einer einzigen Datenbank mit einer guten Sicherung zu beginnen und (zumindest anfänglich) die Komplexität Ihrer Infrastruktur zu minimieren.

Dies scheint, ganz offen gesagt, etwas lächerlich. 16-20 Server, um eine einfache API auszuführen, wenn man bedenkt, dass ein realistisches Projekt wahrscheinlich mehr als 4-5 Dienste haben wird? Gibt es ein grundlegendes Konzept, das mir fehlt, um dies zu erklären?

Für eine einfache API stimmen diese Zahlen nicht überein. Achten Sie darauf, wenn Sie nicht in einen der "Microservice First" fallen Fallen .

1
Dherik

Microservices sind eine Form der serviceorientierten Architektur, vielleicht im Extremfall. Ihr allgemeiner Zweck besteht darin, die Kopplung zu verringern und eine unabhängige Entwicklung und Bereitstellung zu ermöglichen.

In architektonischer Hinsicht ist Microservices ein Begriff, der beispielsweise auf logischer Ebene gilt. Die Mikrodienste sind logisch voneinander getrennt. Aus dieser Perspektive sollten Mikrodienste jeweils einen eigenen Speicher besitzen und vorsehen, der von der Speicherung anderer Mikrodienste entkoppelt werden sollte. Für Microservices ist diese Unabhängigkeit von der Speicherung der Schlüssel zu ihrem Ziel der Modularität und der losen Kopplung.

Aus architektonischer Sicht gilt die horizontale Skalierung auf einer niedrigeren Ebene, näher an der Implementierung, beispielsweise auf einer physischen Ebene. Auf dieser Ebene implementieren wir einen Mikrodienst, und wir können diesen einzelnen Mikrodienst intern in eine zustandslose Komponente zerlegen, die horizontal skalierbar ist, und in eine zustandsbehaftete Komponente, die von allen zustandslosen Komponenten gemeinsam genutzt wird. Aber verwechseln wir nicht nur den zustandslosen Teil allein mit dem Microservice selbst.

Wenn wir also über die einzelnen Mikrodienste sprechen, sprechen wir auf der logischen Ebene über APIs und getrennte Verantwortlichkeiten und getrennte Entwicklungs-/Bereitstellungszyklen. Und wenn wir über horizontale Skalierung sprechen, sprechen wir auf physikalischer Ebene über die Implementierung eines (einzelnen) Mikrodienstes und dessen Zerlegung in zustandslose und zustandsbehaftete Komponenten.

Bei der Implementierung mehrerer Microservices haben wir die Wahl, die Datenbanktechnologie für die Stateful-Komponenten wiederzuverwenden:

  • separate Datenbank pro Microservice
  • gemeinsame Datenbank mit:
    • separates/privates Schema pro Microservice
    • separate/private Tabellen pro Microservice

Weitere Informationen hier .

Ein einziger Datenbankdienst, der von allen Mikrodiensten gemeinsam genutzt wird - dies scheint den Vorteil einer losen Kopplung vollständig auszuschließen.

Einverstanden, wenn Sie das Teilen von Tabellenzeilen und -spalten meinen, wäre das nicht wirklich Microservices.

Wenn wir in unseren Denkprozessen den logischen Begriff der Mikrodienste von dem physikalischeren Begriff der zustandsbehafteten und zustandslosen Komponenten eines Mikrodienstes entkoppeln können, fällt es uns möglicherweise leichter, die von Mikrodiensten angebotene lose Kopplung zu erreichen, während die Effizienz eines gemeinsamen Dienstes erhalten bleibt Datenbanken.

Im Allgemeinen wird eine ganze Menge über Microservices und Stateful Persistence geschrieben, siehe auch hier .

0
Erik Eidt