Wenn Eventual Consistency ein Problem ist

Was ist Eventual Consistency?

Eine IT-Anwendungslandschaft ist nie monolithisch, auch wenn einzelne Komponenten durchaus diese Eigenschaft besitzen können - hier ein großes CRM-System, da das CMS, dort die Buchhaltungssoftware. In der Regel können diese Systeme unabhängig voneinander operieren, aber manchmal reicht das nicht aus. Denn die Daten, mit denen die Systeme arbeiten, sind nicht immer unabhängig voneinander.

Der Kunde, der im CRM hinterlegt ist, ist derselbe Kunde, für den an anderer Stelle die Rechnungen geschrieben werden. Wenn die Adresse im CRM sich geändert hat, dann sollte das auch bei der Rechnungsstellung berücksichtigt werden. Wenn die Rechnungsstellung eigene Daten führt, die mit dem CRM synchronisiert werden müssen, dann gibt es einen Zeitraum, in dem die Daten der Rechnungsstellung noch nicht wieder identisch zu den Daten des führenden CRM sind. Erst wenn die Synchronisierung abgeschlossen ist, sind die Daten wieder konsistent.

Das bezeichnet man als Eventual Consistency. Im Zeitraum zwischen Veränderung der Daten im führenden System und Veränderung im abhängigen System können Dinge geschehen, die wir eigentlich nicht wollen.

Eventual Consistency ist nicht per se ein Problem. Sie ist obendrein in verteilten Systemen die Regel, nicht die Ausnahme, auch wenn wir so selten mit den negativen Folgen konfrontiert werden, dass wir gerne ignorieren, dass es sie gibt. Aber wenn wir z. B. eine E-Mail verschicken, dann ist die versendete Information nur “eventually consistent”. Erst wenn sie empfangen und auch gelesen wurde, ist die enthaltene Information bei Sender und Empfänger wieder konsistent. Das kann ein guter Grund sein, zum Telefon zu greifen, um Fehlentscheidungen aufgrund nicht synchronisierter Informationsstände zu vermeiden.

Was unterscheidet Telefon und E-Mail? Aus Sicht der IT ihre Eigenschaften als

  • synchron bzw. gekoppelt (Telefon) und
  • asynchron bzw. entkoppelt (E-Mail).

Eventual Consistency ist also offensichtlich eine Eigenschaft, die mit Entkopplung bzw. Asynchronität ihren Einzug hält. Was A weiß, weiß B noch lange nicht.

Fünf Varianten, um mit der Eventual Consistency umzugehen

Nun basieren die meisten modernen IT-Architekturen auf dem Prinzip einer höheren Unabhängigkeit der Komponenten untereinander, was zwangsläufig bedeutet, dass Kommunikationsprozesse zwischen ihnen idealerweise komplett asynchron ablaufen. Das stellt die technische Abbildung fachlicher Prozesse vor einige spannende Herausforderungen, für die es verschiedene Lösungsmuster und Antworten gibt.

Variante 1: Gar nicht

Wie oben bereits angedeutet, geht man in den meisten Fällen gar nicht mit Eventual Consistency um. Das ist nicht schlimm, weil oft entweder

  • kein Schaden entsteht oder
  • selten Schaden entsteht, der aber dem Fachprozess bzw. Geschäft nicht nachhaltig zusetzt.

Wenn also auf einer Rechnung noch die alte Adresse erscheint, dann ist das zwar nicht richtig, aber in der Regel auch nicht weiter schlimm. Das Geld wird trotzdem bezahlt.

Warum dies keine Lösung ist:

Wenn im obigen Beispiel die Sendung an die alte Lieferadresse geschickt wird, liegt der Fall anders. Hierdurch entstehen echte Kosten an verschiedenen Stellen (Neuverpackung und -versand, verzögerte Lieferung und Verärgerung, eventuell gar Verlust des Kunden, Personalkosten für die Fallklärung und -bearbeitung).

Wichtig ist also, die Entscheidung, nichts zu tun, bewusst zu treffen (und keine grundsätzliche Regel daraus zu machen). Ist “nichts tun” keine Lösung, werden andere Antworten gebraucht.

Variante 2: Keine redundanten Daten

Eventual Consistency entsteht, wenn Daten führend in einem anderen System verwaltet und verändert, aber nur aus einer lokalen (und damit redundanten) Kopie gelesen werden. Solange die Kopie nicht den gleichen Stand wie das Original hat, sind die Daten nicht konsistent. Anstatt also eine lokale Kopie zu erstellen, werden die Daten bei Bedarf aus dem führenden System angefragt. Damit ist sichergestellt, dass der dort existierende aktuelle Datenstand als Grundlage der lokalen Prozesse verwendet wird.

Warum ist das keine Lösung?

Zum einen hat die ständige Anfrage des aktuellen Datenstandes ihren Preis:

  • Das führende System muss Schnittstellen für entsprechende Anfragen bereit stellen. Diese müssen adressatengerecht die angeforderten Daten liefern. Die Bereitstellung der entsprechenden Funktionen erfordert zusätzliche Entwicklungsaufwände.
  • Die Anfragen beeinflussen die Performance des führenden Systems. In welchem Umfang das der Fall ist, ist beim Design der Kommunikations- und Fachprozesse zu gestalten und abzuschätzen, damit es im Betrieb nicht zu Überraschungen kommt.

Wichtiger aber ist, dass dieses Verfahren dann scheitert, wenn ein konsistenter Datenstand sich aus mehr als einem System zusammensetzen muss.

Schritt 1:
System A löst über eine Nachricht je einen Prozess in System B und System C aus. System A hat seine Daten bereits fortgeschrieben. Sie bilden den neuen Zustand der Welt (S2) ab. Diesen kennen System B und System C noch nicht. (Abbildung)

Redundante Daten

Schritt 2:
System C braucht während seiner Prozessdurchführung zusätzlich zu Daten aus System A auch Daten, die System B im Zuge seiner Aufgaben erzeugt. Es stellt eine Anfrage an beide Systeme.

  • System A liefert den aktuellen Datenstand.
  • System B hat bis zum Zeitpunkt der Anfrage von System C seinen Prozess noch nicht abgeschlossen. Der “aktuelle” Datenstand, der an System C geliefert wird, ist daher - bezogen auf den Gesamtprozess - veraltet (S1).
Redundante Daten

Variante 3: Synchronisierende Transaktion

Wenn die Synchronisierung ein zwingend erforderlicher Schritt ist, um Daten über Systemgrenzen konsistent zu halten, dann kann eine Synchronisierung in die Transaktion aufgenommen werden, die die Daten im führenden System verändert. Die Transaktion ist die Klammer, die mehrere Prozessschritte zusammenfasst und sie gemeinsam entweder ganz oder gar nicht abschließt (z. B. eine Sollbuchung immer mit der korrespondierenden Habenbuchung).

Warum dies ebenfalls keine Lösung ist:

Eine Transaktion in einem verteilten System ist komplexer als in einem geschlossenen, lokalen System. Die besondere Herausforderung besteht darin, die Schritte in verschiedenen Anwendungen so zu koordinieren, dass entweder Freigabe (Commit) oder Zurückdrehen der Änderungen (Rollback/Compensation) über Systemgrenzen hinweg funktionieren. Entwurfsmuster, die hier zum Einsatz kommen, heißen Two- oder Three-Phase-Commit und haben mit dem Saga-Pattern einen nahen Verwandten.

Dabei sind diese Entwurfsmuster nicht absolut sicher. Es gibt stets eine letzte Lücke, die bei einer Störung zu einem Scheitern des Prozesses führen kann. Die Wahrscheinlichkeit dafür wird allerdings so gering, dass sie (fast) ignoriert werden kann.

Das Problem der Eventual Consistency schaffen die Entwurfsmuster ohnehin nicht komplett aus der Welt. Wenn ein unabhängiger Prozess vor Abschluss der Synchronisierung auf die noch nicht aktualisierten Daten zugreifen möchte, erhält er den alten Stand, obwohl er vielleicht fachlich schon auf den Prozess folgt, der die Synchronisierung auslöst. Es werden dann weitere Steuerungsmechanismen benötigt, um dieses Problem zu lösen (z. B. globale Semaphore, die Zugriffe auf in Veränderung befindliche Objekte verhindern; siehe auch nächste Variante).

Variante 4: Mehr Metadaten

Es gibt weitere Methoden, um mit Eventual Consistency umzugehen. Metadaten als Teil der Kommunikation oder die Kommunikation begleitend können Reihenfolgen absichern, Klarheit über die letzten Verarbeitungsstände oder zuletzt veränderten Objekte schaffen.

Dies ist jedoch auch keine Lösung

Es gibt mannigfaltige Möglichkeiten, wie Metadaten eingesetzt werden können. Gemeinsames Merkmal ist aber stets, dass über einen Umweg - nämlich die Auswertung der Metadaten - Klarheit über den Grad der Konsistenz geschaffen wird. Das ist zum einen nicht ganz unkompliziert und zum anderen sehr spezifisch auf die Domäne abzustellen, weil die fachliche Logik die prozessualen Abhängigkeiten und damit die Informationsanforderungen an die Metadaten definieren.

Bei genauerem Hinsehen stellt sich außerdem heraus, dass die Metadaten einen weiteren Effekt haben: Sie blockieren Prozesse. Denn sie dienen dazu, einen Systemzustand bzw. den Grad der benötigten Konsistenz festzustellen. Ist dieser benötigte Grad aber nicht vorhanden, so muss er abgewartet werden.

Moderne IT-Architekturen, insbesondere Microservice-Architekturen, zeichnen sich dadurch aus, dass die verschiedenen Prozesse idealerweise nichts übereinander wissen müssen. Sie haben ihre spezifische Aufgabe und verwalten die dafür benötigten Daten selbst. Metadaten hebeln diese Unabhängigkeit in dem Sinne aus, dass sie einen übergreifenden Zusammenhang zwischen den Datenbeständen und Prozessen herstellen, was die Freiheit der Systemkomponenten limitiert.

Zwischenstand: Houston, wir haben ein Problem!

Aus rein algorithmischer Sicht gibt es für die meisten Herausforderungen eine Lösung. Aber dass es einen brauchbaren Algorithmus gibt, ist nur ein Teil der Antwort. Denn jeder zusätzlich benötigte Algorithmus ist ein Kompromiss: Was ich auf der einen Seite an reiner Machbarkeit gewinne, bezahle ich an anderer Stelle durch zusätzlichen Entwicklungsaufwand, höhere Komplexität (und geringere Wartbarkeit), niedrigere Systemperformance (und höhere Transaktionskosten). Das Risiko einer fehlerhaften Fachlichkeit sinkt, aber andere Risiken steigen dafür.

Es gibt heutzutage viele IT-Architekten, die mit den Schultern zucken und sagen: “Ist eben so! Entkoppelte Systeme sind wichtig, also muss man das akzeptieren.” Ihre Empfehlung lautet, die Systeme so zu schneiden, dass Eventual Consistency kein Problem wird. Aber alle Teile eines Anwendungssystems beisammen zu halten, die eine konsistente Sicht auf die Daten brauchen, führt häufig zu sehr großen Komponenten. Große (monolithische) Komponenten sind aber, das haben wir in den letzten Jahrzehnten gelernt, nicht wünschenswert. Außerdem ist das mit dem Schneiden (oder Zusammenlegen) oft gar keine Entscheidung, die noch getroffen werden kann, weil Teile der Gesamtarchitektur schon da und somit Zuständigkeiten und Datenhoheiten schon definiert sind.

Eventual Consistency haftet also eine gewisse Unumgänglichkeit an - in modernen IT-Architekturen sogar in besonderem Maße, weil diese entkoppelt und kleinteilig sein müssen, um die versprochenen Effizienzvorteile zu heben. Weil aber “schön” nicht “schön falsch” werden darf, müssen die oben beschriebenen Lösungsvarianten für das Problem der Eventual Consistency ebenfalls in die Architektur integriert werden. Das geschieht je nach Bedarf einzeln oder auch in Kombination miteinander.

Der Umgang mit Eventual Consistency ist vor allem eines: teuer. Die Gegenmaßnahmen kosten einiges, sowohl in der Konzeption und Entwicklung als auch in der Wartung. Und wenn es doch zu einem fachlichen Fehler aufgrund der technisch begründeten Eventual Consistency kommt, dann ist die Ursachenanalyse schwierig (von der Behebung mal ganz abgesehen).

Das Problem der Eventual Consistency ist also nicht ihr Wirken. Es sind die Maßnahmen, die wir ergreifen müssen, ihr entgegen zu wirken.

Früher war alles besser?

Die Antithese ist einfach: Früher, in Zeiten monolithischer Anwendungen mit großen relationalen Datenbanken, da gab es solche Probleme nicht. Denn früher war alles besser. Das ist genauso richtig wie es falsch ist.

Natürlich ist die Abbildung in einer gemeinsamen Datenbank innerhalb eines monolithischen Systems ein Garant dafür, dass Geschäftsprozesse auf einfache Weise in Transaktionen gekapselt werden können. Die Konsistenz der Daten innerhalb des Monolithen ist gut herstellbar. Aber die Abbildung aller Fachprozesse innerhalb einer gemeinsamen, synchron operierenden Anwendungsarchitektur bringt eben auch all die Schwächen mit sich, die überhaupt erst zu modernen, verteilten Architekturen geführt haben:

  • eine im Laufe der Zeit immer schwierigere Wartung,
  • hohe Komplexität,
  • Wartezustände und Locks,
  • Ressourcenhunger und
  • schlechte Skalierbarkeit.

Das sind keine gewünschten Eigenschaften einer IT-Anwendung. Aber gibt es nicht vielleicht eine Lösung zwischen diesen Extremen?

Variante 5: Etwas Altes, etwas Neues

Lösung Eventual Consistency

Das Problem der Eventual Consistency lässt sich nur lösen, indem Eventual Consistency nicht entsteht. In manchen Konstellationen geht das einfach nicht, z. B. weil die Anwendungen sind wie sie sind und Konsistenz nur über Hilfskonstrukte (Varianten 2 bis 4) sichergestellt werden kann. Das kostet Kraft und birgt Risiken.

Wenn hingegen die gestalterischen Freiheitsgrade vorhanden sind, dann lohnt es sich, über eine Trennung von Daten und Prozessen nachzudenken und beides unterschiedlich zu behandeln. Eine Anwendungslandschaft darf durchaus kleine Komponenten haben, die sich untereinander austauschen und an einer gemeinsamen Aufgabe arbeiten. Wenn aber die Verteilung und redundante Haltung der benötigten Daten zum Problem wird, dann kann es hilfreich sein, die Daten nur an exakt einer Stelle abzulegen. Ein paar Freiheiten werden auf diese Weise aufgegeben, aber ein erhebliches Maß an Komplexität verschwindet ebenfalls aus der Architektur. Moderne Datenbanken bringen frei Haus aus eine Menge hilfreicher Konzepte mit, z. B.

  • Transaktionen/Commit und Rollback
  • Locking von Objekten/Isolation Levels

Um genau diese Qualitäten zu nutzen, muss das Schreiben und Lesen von Daten über einen Orchestrierungsservice laufen, der einen abstrakten Transaktionsbegriff in verteilten Systemen unterstützt und im Hintergrund für einen konsistenten Zustand der Daten sorgt. Dieser Orchestrierungsservice zentralisiert die Datenhoheit. Das entspricht im Kern der Idee der explizit für Datenzugriffe ausgelegten Schicht einer Mehrschichtarchitektur. Die Besonderheit hier ist die Verschränkung zweier eigentlich inkompatibler Paradigmen: ein zentraler, zustandsbehafteter, individueller Service für das Management von Datenzugriffen auf der einen Seite und ein verteiltes, lose gekoppeltes System mit asynchroner Kommunikation auf der anderen Seite.

Schwerer wiegt für viele IT-Architekten aber der Umstand, dass die Komponenten des verteilten Systems keine unabhängigen Entscheidungen mehr bezüglich der Datenstruktur und -speicherform treffen können. Das ist richtig, sofern es die übergreifend konsistent zu haltenden Daten betrifft. Für alle Daten hingegen, die nur lokal genutzt und verändert werden (und die somit von Eventual Consistency nicht betroffen sind), gilt weiterhin völlige Freiheit. Auch Daten, für die Eventual Consistency überhaupt kein Problem darstellt, weil die temporäre Inkonsistenz keinen Einfluss auf die Fachlichkeit besitzt, können weiterhin verteilt und individuell bewirtschaftet werden.

Im Diagramm stellt sich diese Variante wie folgt dar (s. Abbilldung).

Als Vorteil einer lediglich in den Komponenten verankerten Datenhaltung wird gerne genannt, dass Datenmodelländerungen immer lokal und jederzeit erfolgen können, ohne dass das Einfluss auf andere Komponenten haben muss. Das ist zwar im Prinzip richtig, lässt aber außer Acht, dass es meist nur ein, insbesondere recht stabiles Modell der Fachlichkeit mit seinen Eigenschaften gibt. Dieses unterliegt nach einer Reifungsphase meist nur moderaten Veränderungen. Diese wiederum in einem (relationalen) Datenmodell nachzuziehen, bedarf einer gewissen Sorgfalt, ist aber mitnichten eine Raketenwissenschaft. Erst wenn die Fachlichkeit häufigen und schwerwiegenderen Veränderungen unterliegt, ist die verteilte Datenhaltung wieder im Vorteil.

Fazit

Eventual Consistency ist keine wünschenswerte Eigenschaft einer IT-Architektur, wenn Datenkonsistenz über Komponenten hinweg zwingend hergestellt werden muss. Es gibt genügend Konzepte, die mit diesem Problem umgehen können. Allen gemein ist, dass sie einen Kompromiss erfordern. Versucht man, die Eigenschaften einer modernen Architektur dabei vollständig zu erhalten, dann erhöht das die Komplexität und damit Kosten und Risiken. Schraubt man hingegen die architekturellen Ambitionen zurück, so gibt man zwangsläufig einige der Vorteile auf, die eine verteilte, hoch skalierbare Architektur bieten kann. Dafür reduziert sich aber die Komplexität der Lösung.

Persönlich tendiert der Autor zur Variante 5, insbesondere aufgrund der Erfahrungen mit Projekten, bei denen ein maximal entkoppelter Ansatz versucht wurde.

Entweder

  • hatten diese erhebliche Probleme mit der Komplexität der technischen Abbildung der fachlichen Anforderungen oder
  • es wurden nicht alle nötigen Verfahren implementiert, um die Datenkonsistenz verlässlich herzustellen.

Die Ambitionen in IT-Projekten lösen sich gerne einmal von den Notwendigkeiten und Gegebenheiten der Fachlichkeit. Das ist ein Missverhältnis, das bei der Gestaltung einer Anwendungslandschaft höchst ungesund ist. Eine gute IT-Architektur ist eine, die von uns beherrscht wird und nicht umgekehrt. Die wahre Herausforderung ist es, technischen Idealismus und funktionale Nüchternheit auf die beste Weise zu verheiraten.

Ihr Ansprechpartner zur Eventual Consistency

Sie möchten sich näher mit dem Thema beschäftigen und eine adäquate Lösung finden?
Sprechen Sie unseren Technology Lead für Data Centric Solutions & AI gerne an.

Dirk Heche, Aleri Solutions

Dirk Heche

Technology Lead: Data Centric Solutions & AIdirk.heche@aleri.de

Das könnte Sie auch interessieren

Aktuell gibt es leider keine zu Ihrer Filtereinstellung passenden Treffer. Die Auswahl beruht auf vorherigen, von Ihnen gemachten Angaben. Ändern Sie Ihre Wünsche in den Einstellungen, wenn Sie andere Inhalte angezeigt bekommen möchten.

Seite teilen