Dichotomie von Daten: Überdenken der Beziehung zu Daten und Diensten

Hallo alle zusammen! Wir haben gute Neuigkeiten, im Juni wird OTUS erneut den Kurs „Software Architect“ starten , in dessen Zusammenhang wir traditionell nützliches Material mit Ihnen teilen.




Wenn Sie mit Microservices ohne Kontext auf diese ganze Geschichte stoßen, können Sie sie als etwas seltsam betrachten. Das Partitionieren der Anwendung in Fragmente, die durch ein Netzwerk verbunden sind, bedeutet natürlich, dem resultierenden verteilten System komplexe Fehlertoleranzmodi hinzuzufügen.

Trotz der Tatsache, dass dieser Ansatz die Aufteilung in viele unabhängige Dienste umfasst, ist das Endziel viel mehr als nur der Betrieb dieser Dienste auf verschiedenen Maschinen. Wir sprechen über die Interaktion mit der Außenwelt, die im Wesentlichen auch verteilt ist. Nicht im technischen Sinne, sondern im Sinne eines Ökosystems, das aus vielen Menschen, Teams, Programmen besteht, und jeder dieser Teile muss irgendwie seinen Job machen.

Unternehmen sind beispielsweise eine Reihe verteilter Systeme, die zusammen zur Erreichung eines bestimmten Ziels beitragen. Wir haben diese Tatsache jahrzehntelang ignoriert und versucht, eine Vereinheitlichung zu erreichen, Dateien über FTP zu übertragen oder Tools zur Unternehmensintegration zu verwenden, während wir uns auf unsere persönlichen isolierten Ziele konzentrieren. Aber mit dem Aufkommen der Dienste hat sich alles geändert. Services haben uns geholfen, über den Horizont hinauszuschauen und die Welt der voneinander abhängigen Programme zu sehen, die zusammenarbeiten. Um jedoch erfolgreich arbeiten zu können, müssen zwei grundlegend unterschiedliche Welten verwirklicht und gestaltet werden: die Außenwelt, in der wir in einem Ökosystem vieler anderer Dienstleistungen leben, und unsere persönliche Innenwelt, in der wir allein regieren.



Eine solche verteilte Welt unterscheidet sich von der, in der wir aufgewachsen sind und an die wir gewöhnt sind. Die Prinzipien des Aufbaus traditioneller monolithischer Architektur halten Kritik nicht stand. Ein korrektes Verständnis solcher Systeme ist daher mehr als das Erstellen eines Klassenzimmerdiagramms auf einer weißen Markierungstafel oder eines coolen Proof of Concept. Es geht um ein solches System, das lange Zeit erfolgreich funktioniert. Glücklicherweise gibt es Dienste schon seit einiger Zeit, obwohl sie anders aussehen. SOA-Lektionen sind immer noch relevant, sogar mit Docker, Kubernetes und leicht angeschlagenen Hipster-Bärten gewürzt.

Heute schauen wir uns also an, wie sich die Regeln geändert haben, warum wir unsere Herangehensweise an die Dienste und Daten, die sie untereinander übertragen, überdenken müssen und warum wir dafür völlig andere Tools benötigen.

Die Kapselung wird nicht immer dein Freund sein


Microservices können unabhängig voneinander arbeiten. Es ist diese Eigenschaft, die ihnen den größten Wert gibt. Mit derselben Eigenschaft können Services skaliert und erweitert werden. Nicht so sehr in Bezug auf die Skalierung auf Billiarden Benutzer oder Petabyte an Daten (obwohl sie hier helfen können), sondern in Bezug auf die Skalierung aus Sicht der Menschen, da Teams und Organisationen kontinuierlich wachsen.



Unabhängigkeit ist jedoch ein zweischneidiges Schwert. Das heißt, der Dienst selbst kann sich leicht und natürlich drehen. Wenn jedoch eine Funktion innerhalb des Dienstes implementiert ist, die die Verwendung eines anderen Dienstes erfordert, müssen wir am Ende fast gleichzeitig Änderungen an beiden Diensten vornehmen. Im Monolithen ist dies einfach zu bewerkstelligen. Nehmen Sie einfach eine Änderung vor und senden Sie sie an die Version. Bei der Synchronisierung unabhängiger Dienste treten jedoch weitere Probleme auf. Die Koordination zwischen Teams und Release-Zyklen zerstört die Flexibilität.



Als Teil des Standardansatzes werden lästige End-to-End-Änderungen einfach vermieden, wodurch die Funktionalität klar zwischen den Diensten aufgeteilt wird. Der Single Sign-On-Service hier kann ein gutes Beispiel sein. Er hat eine klar definierte Rolle, die ihn von anderen Diensten unterscheidet. Eine solch klare Trennung bedeutet, dass sich in einer Welt sich schnell ändernder Anforderungen an die umgebenden Dienste der Single Sign-On-Dienst wahrscheinlich nicht ändern wird. Es existiert in einem streng begrenzten Kontext.



Das Problem ist, dass Unternehmensdienste in der realen Welt nicht ständig eine ebenso saubere Rollentrennung aufrechterhalten können. Beispielsweise funktionieren dieselben Geschäftsdienste eher mit Daten, die von anderen ähnlichen Diensten stammen. Wenn Sie im Online-Handel tätig sind, wird die Verarbeitung des Bestellflusses, des Produktkatalogs oder der Benutzerinformationen für viele Ihrer Dienste zur Voraussetzung. Jeder der Dienste benötigt Zugriff auf diese Daten, um funktionieren zu können.


Die meisten Unternehmensdienste verwenden denselben Datenstrom, sodass ihre Arbeit immer miteinander verflochten ist.

Wir kommen also zu einem wichtigen Punkt, über den es sich zu sprechen lohnt. Während Services für Infrastrukturkomponenten gut funktionieren, die weitgehend voneinander getrennt sind, sind die meisten Business Services stärker miteinander verflochten.

Datendichotomie


Möglicherweise gibt es bereits dienstorientierte Ansätze, aber es gibt noch wenig Informationen darüber, wie große Datenmengen zwischen Diensten ausgetauscht werden können.

Das Hauptproblem ist, dass Daten und Dienste untrennbar miteinander verbunden sind. Einerseits ermutigt uns die Kapselung, Daten zu verbergen, damit Dienste voneinander getrennt werden können und ihr Wachstum und weitere Änderungen erleichtern. Auf der anderen Seite müssen wir in der Lage sein, allgemeine Daten sowie alle anderen Daten frei zu teilen und zu regieren. Es geht darum, sofort mit der Arbeit beginnen zu können, so frei wie in jedem anderen Informationssystem.

Informationssysteme haben jedoch wenig mit Kapselung zu tun. In der Tat sogar das Gegenteil. Datenbanken tun alles, um Zugriff auf die darin gespeicherten Daten zu gewähren. Sie verfügen über eine leistungsstarke deklarative Oberfläche, mit der Sie die Daten nach Bedarf ändern können. Diese Funktionalität ist in der Phase der Vorforschung wichtig, jedoch nicht für die Bewältigung der wachsenden Komplexität eines sich ständig weiterentwickelnden Dienstes.



Und hier entsteht ein Dilemma. Widerspruch. Dichotomie. Bei Informationssystemen geht es schließlich um die Bereitstellung von Daten, und bei Diensten geht es um die Verschleierung.

Diese beiden Kräfte sind grundlegend. Sie bilden die Grundlage für den größten Teil unserer Arbeit und streben ständig nach Spitzenleistungen in den von uns erstellten Systemen.

Während Service-Systeme wachsen und sich weiterentwickeln, sehen wir unterschiedliche Manifestationen der Auswirkungen der Datendichotomie. Entweder wird die Serviceschnittstelle wachsen, einen immer breiteren Funktionsumfang bieten und wie eine wunderbare, selbst erstellte Datenbank aussehen, oder wir werden enttäuscht sein und eine Möglichkeit implementieren, ganze Datensätze von Service zu Service zu extrahieren oder zu verschieben.



Das Erstellen von Daten, die wie eine wunderbare, selbst erstellte Datenbank aussehen, führt wiederum zu einer Reihe von Problemen. Wir werden nicht näher darauf eingehen, was die gemeinsam genutzte Datenbank gefährlich ist, sondern nur sagen, dass sie für das Unternehmen, das versucht, sie zu verwenden, erhebliche kostspielige technische und betriebliche Schwierigkeiten mit sich bringt .

Schlimmer noch, Datenmengen vervielfachen Probleme mit Dienstgrenzen. Je häufiger Daten im Dienst enthalten sind, desto komplizierter wird die Schnittstelle und desto schwieriger wird es, die Datensätze verschiedener Dienste zu kombinieren.

Ein alternativer Ansatz zum Extrahieren und Verschieben ganzer Datensätze hat ebenfalls Probleme. Ein gängiger Ansatz für dieses Problem besteht darin, den gesamten Datensatz einfach zu extrahieren, zu speichern und dann lokal in jedem Verbraucherdienst zu speichern.



Das Problem ist, dass verschiedene Dienste die von ihnen verbrauchten Daten unterschiedlich interpretieren. Diese Daten sind immer zur Hand. Sie werden lokal geändert und verarbeitet. Ziemlich schnell haben sie nichts mehr mit den Daten in der Quelle gemeinsam.


Je veränderlicher die Kopien sind, desto mehr variieren die Daten im Laufe der Zeit.

Schlimmer noch, solche Daten sind im Nachhinein schwer zu korrigieren ( MDM kann hier wirklich Abhilfe schaffen). Tatsächlich sind einige der unlösbaren technologischen Probleme, mit denen ein Unternehmen konfrontiert ist, auf die Vervielfältigung heterogener Daten von Anwendung zu Anwendung zurückzuführen.

Um eine Lösung für dieses Problem mit gemeinsam genutzten Daten zu finden, müssen Sie anders denken. Sie sollten in den von uns erstellten Architekturen zu erstklassigen Objekten werden. Pat hellandnennt solche Daten "extern", und dies ist ein sehr wichtiges Merkmal. Wir benötigen eine Kapselung, um die interne Struktur des Dienstes nicht freizulegen, aber wir müssen den Diensten den Zugriff auf gemeinsam genutzte Daten erleichtern, damit sie ihre Arbeit korrekt ausführen können.



Das Problem ist, dass keiner der Ansätze heute relevant ist, da weder die Dienstschnittstellen noch das Messaging oder die gemeinsam genutzte Datenbank eine gute Lösung für die Arbeit mit externen Daten bieten. Serviceschnittstellen sind für den Datenaustausch in jeder Größenordnung schlecht geeignet. Messaging verschiebt Daten, speichert jedoch nicht den Verlauf, sodass Daten im Laufe der Zeit beschädigt werden. Freigegebene Datenbanken konzentrieren sich zu sehr auf einen Punkt, was den Fortschritt hemmt. Wir befinden uns unweigerlich in einem Datenfehlerzyklus:


Dateninsolvenzzyklus

Streams: Ein dezentraler Ansatz für Daten und Dienste


Im Idealfall müssen wir den Ansatz ändern, wie Dienste mit gemeinsam genutzten Daten funktionieren. Im Moment ist jeder Ansatz mit der oben erwähnten Zweiteilung konfrontiert, da es keinen magischen Pollen gibt, der großzügig darauf gestreut und so hergestellt werden könnte, dass er verschwindet. Wir können das Problem jedoch überdenken und zu einem Kompromiss kommen.

Dieser Kompromiss beinhaltet einen gewissen Grad an Zentralisierung. Wir können den verteilten Protokollmechanismus verwenden, da er zuverlässige skalierbare Abläufe bietet. Jetzt brauchen wir Dienste, um diesen gemeinsamen Threads beitreten und mit ihnen arbeiten zu können. Wir möchten jedoch die komplexen zentralisierten Gottesdienste vermeiden, die diese Verarbeitung ausführen. Daher ist die beste Option, die Streaming-Verarbeitung in jeden Verbraucherdienst einzubetten. So können Dienste Datensätze aus verschiedenen Quellen kombinieren und bei Bedarf mit ihnen arbeiten.

Eine Möglichkeit, diesen Ansatz zu erreichen, ist die Verwendung einer Streaming-Plattform. Es gibt viele Möglichkeiten, aber heute werden wir Kafka in Betracht ziehen, da die Verwendung seiner Stateful Stream Processing es uns ermöglicht, das vorgestellte Problem effektiv zu lösen.



Die Verwendung des verteilten Protokollierungsmechanismus ermöglicht es uns, einem ausgetretenen Pfad zu folgen und Messaging zu verwenden, um mit einer ereignisorientierten Architektur zu arbeiten . Es wird angenommen, dass dieser Ansatz eine bessere Skalierung und Trennung bietet als der Anforderungs-Antwort-Mechanismus, da er dem Empfänger und nicht dem Sender die Kontrolle über den Fluss gibt. Sie müssen jedoch für alles in diesem Leben bezahlen, und hier brauchen Sie einen Makler. Aber für große Systeme lohnt sich dieser Kompromiss (was nicht über Ihre durchschnittlichen Webanwendungen gesagt werden kann).

Wenn ein Broker für die verteilte Protokollierung verantwortlich ist und kein herkömmliches Messagingsystem, können Sie zusätzliche Funktionen nutzen. Der Transport kann fast genauso linear linear skaliert werden wie ein verteiltes Dateisystem. Daten können lange Zeit in den Protokollen gespeichert werden, sodass wir nicht nur Nachrichten, sondern auch Informationen speichern können. Skalierbare Lagerung ohne Angst vor einem veränderlichen Allgemeinzustand.

Anschließend können Sie den Stateful-Stream-Verarbeitungsmechanismus verwenden, um Consumer Services deklarative Datenbank-Tools hinzuzufügen. Dies ist ein sehr wichtiger Punkt. Während Daten in gemeinsam genutzten Streams gespeichert werden, auf die alle Dienste zugreifen können, ist das Pooling und die Verarbeitung durch den Dienst privat. Sie befinden sich in einem streng begrenzten Kontext isoliert.


Beseitigen Sie die Zweiteilung von Daten, indem Sie den Immunfluss von Zuständen teilen. Fügen Sie diese Funktion dann jedem Dienst mithilfe der Stateful Stream-Verarbeitung hinzu.

Wenn Ihr Service also mit Bestellungen, einem Produktkatalog oder einem Lager arbeiten muss, hat er vollen Zugriff: Nur Sie entscheiden, welche Daten kombiniert werden sollen, wo sie verarbeitet werden sollen und wie sie sich im Laufe der Zeit ändern sollen. Trotz der Tatsache, dass die Daten allgemein sind, ist die Arbeit mit ihnen vollständig dezentralisiert. Es wird in jedem Dienst hergestellt, in einer Welt, in der alles nach Ihren Regeln verläuft.


Teilen Sie Daten, damit ihre Integrität nicht verletzt wird. Kapselung einer Funktion, nicht einer Quelle, in jedem Dienst, der sie benötigt.

Es kommt also vor, dass die Daten massiv verschoben werden müssen. Manchmal erfordert ein Dienst einen lokalen Verlaufsdatensatz in einem ausgewählten Datenbankmodul. Der Trick besteht darin, dass Sie sicherstellen können, dass bei Bedarf eine Kopie von der Quelle wiederhergestellt werden kann, indem Sie auf den verteilten Protokollierungsmechanismus zugreifen. Die Steckverbinder von Kafka leisten hier hervorragende Arbeit.

Der heute betrachtete Ansatz hat also mehrere Vorteile:

  • Daten werden in Form von gemeinsam genutzten Streams verwendet, die für eine lange Zeit in den Protokollen gespeichert werden können, und der Mechanismus für die Arbeit mit gemeinsam genutzten Daten ist in jedem einzelnen Kontext verkabelt, sodass Dienste schnell und einfach arbeiten können. Auf diese Weise können Sie die Dichotomie der Daten ausgleichen.
  • , , . .
  • Stateful Stream Processing , , .
  • , , , -.
  • , . , .
  • , .

Wie Sie sehen können, ist dies mehr als nur REST. Wir haben eine Reihe von Tools, mit denen Sie dezentral mit gemeinsam genutzten Daten arbeiten können.

Im heutigen Artikel wurden nicht alle Aspekte offenbart. Wir müssen noch entscheiden, wie das Anforderungs- / Antwort-Paradigma und das ereignisorientierte Paradigma ausgeglichen werden sollen. Aber wir werden uns das nächste Mal darum kümmern. Es gibt Themen, die Sie besser kennenlernen müssen, zum Beispiel, warum Stateful Stream Processing so gut ist. Wir werden im dritten Artikel darüber sprechen. Und es gibt andere leistungsstarke Designs, die wir verwenden können, wenn wir auf sie zurückgreifen, z. B. Exactly Once Processing . Mit seiner Hilfe werden die Spielregeln für verteilte Geschäftssysteme geändert, da dieses Design Transaktionsgarantien für XA bietetin skalierbarer Form. Dies wird im vierten Artikel besprochen. Schließlich müssen wir die Einzelheiten der Umsetzung dieser Grundsätze durchgehen.



Denken Sie jedoch vorerst an Folgendes: Eine Datendichotomie ist die Kraft, der wir bei der Erstellung von Unternehmensdiensten ausgesetzt sind. Und wir müssen uns daran erinnern. Der Trick besteht darin, alles auf den Kopf zu stellen und die allgemeinen Daten als erstklassige Objekte zu betrachten. Stateful Stream Processing bietet hierfür einen einzigartigen Kompromiss. Er vermeidet die zentralisierten „Gottkomponenten“, die den Fortschritt behindern. Darüber hinaus bietet es die Geschwindigkeit, Skalierbarkeit und Fehlertoleranz von Daten-Streaming-Pipelines und fügt sie jedem Service hinzu. Daher können wir uns auf den allgemeinen Bewusstseinsstrom konzentrieren, mit dem sich jeder Dienst verbinden und mit seinen Daten arbeiten kann. Die Dienste sind also skalierbarer, austauschbarer und autonomer. Daher sehen sie nicht nur auf Whiteboards und beim Testen von Hypothesen gut aus.sondern auch seit Jahrzehnten arbeiten und entwickeln.



.



All Articles