Operations heute und morgen, Teil 4: Hochverfügbarkeit

Seite 2: Infrastruktur, Fehlertoleranz

Inhaltsverzeichnis

Folgt man dem ersten Ansatz und möchte die MTTF erhöhen, kommen dafür typischerweise redundante Infrastrukturbausteine zum Einsatz, etwa Cluster und mehrfach ausgelegte Netzwerkverbindungen. Diese Form der Redundanz adressiert in der Regel Fehlerquellen unterhalb der Anwendungsebene, primär bezogen auf das Ausfallen der Hardware- und Infrastrukturkomponenten. Es handelt sich um eine prophylaktische Maßnahme, die Eintrittswahrscheinlichkeit eines Gesamtausfalls des Systems zu minimieren, und sie beruht auf der Annahme, dass Mängel und Fehlerursachen in mehreren Infrastrukturbausteinen gleichzeitig auftreten, sehr unwahrscheinlich ist.

Der Vorteil für Entwickler ist, dass sie annehmen können, dass die Infrastruktur für ihre Anwendung nahezu 100 Prozent verfügbar ist. Mängel in der Anwendung beziehungsweise auf Anwendungsebene kompromittieren die Verfügbarkeit jedoch weiterhin. Um die dafür nötige Stabilität der Software herzustellen, sind Fehlerursachen zu antizipieren. Ist der Fehler (Störung, Irrtum etc.) einmal bekannt, lässt er sich in der Anwendung abfangen und korrigieren. Zusätzlich wird die Fehlerkonstellation, wenn möglich, mit einem Testfall geprüft, um das "falsche" Verhalten zukünftig zu vermeiden. Neben der eigentlichen Funktionserweiterung kommt es zur kontinuierlichen Verfeinerung und Verbesserung der Stabilität.

Folglich obliegt das Sicherstellen von Hochverfügbarkeit nicht mehr allein nur dem Betrieb, sondern sollte bereits in die Software eingebaut werden. Hier hilft ein iteratives und inkrementelles (agiles) Vorgehen. Ergänzt um DevOps-Prinzipien, ermöglicht die Feedbackschleife aus dem Betrieb zurück in die Entwicklung, gemeinsam zu lernen und geeignete Maßnahmen zu implementieren, um die Verfügbarkeit auszubauen. Es ist illusorisch anzunehmen, dass sich Entwickler, die – wie heute leider häufig noch üblich – vom Betrieb abgeschirmt sind und nur für die möglichst schnelle Umsetzung von Fachanforderungen belohnt werden, viele Gedanken über Verfügbarkeit machen. Vielfach ist das heute immer das alleinige Problem der Betriebsseite.

Heutige Anwendungslandschaften sind ein Netz aus Softwarebausteinen, die auf Cloud-Infrastrukturen-Komponenten ohne besondere Verfügbarkeitszusicherungen betrieben werden. Galt früher, ein "System muss verfügbar sein", heißt es nun, dass eine komplexe und hochgradig vernetzte Anwendungslandschaft verfügbar sein muss.

Wer sich mit verteilten Systemen – und nichts anderes ist eine vernetze Anwendungslandschaft aus vielen, relativ kleinen Bausteinen, die per Netzwerk miteinander kommunizieren – beschäftigt hat, weiß, dass Verfügbarkeit in verteilten Systemen eine besondere Herausforderung ist. Zum einen reduziert jeder beteiligte Baustein die Gesamtverfügbarkeit des Systems. Folglich ist die Kette so stark wie ihr schwächstes Glied, genauer aber ist die Kette schwächer als ihr schwächstes Glied (vgl. [3]). Damit die gesamte Einheit noch eine akzeptable Verfügbarkeit erreicht, sind die einzelnen Bausteine extrem verfügbar auszulegen. Zum anderen ist auch das Netzwerk selbst eine zusätzliche Quelle möglicher Ausfälle. Erschwerend kommt hinzu, dass die Infrastruktur häufig über keine Hochverfügbarkeitsmechanismen verfügt.

Leslie Lamport, einer der führenden Köpfe auf dem Gebiet verteilter Systeme hat salopp, aber treffend formuliert:

"A distributed system is one in which the failure of a computer you didn't even know existed can render your own computer unusable."

Anders ausgedrückt: In einem verteilten System gibt es viele Fehlerquellen, die sein korrektes Funktionieren kompromittieren, und es ist unmöglich, alle vorherzusagen oder gar zu vermeiden. Frei nach Murphy "Alles, was schiefgehen kann, wird auch schiefgehen".

Mit dieser Tatsache vor Augen sollte man sich bewusst werden, ob Verfügbarkeit, Zuverlässigkeit oder beide gefordert sind. Zuverlässige Systeme müssen möglichst lange fehlerfrei funktionieren und erfordern Maßnahmen, die MTTF zu maximieren.

Ein gutes Beispiel sind medizinische Geräte. Ein Fehler kann tödlich enden und ist zu vermeiden. Hochverfügbarkeit ist weniger wichtig, da die Wartung auch ein paar Tage am Stück dauern darf, solange ein Ersatzgerät vorhanden ist. Für viele Anwendungen ist Hochverfügbarkeit jedoch eine essenzielle Anforderung, insbesondere wenn sie von den Endkunden oder anderen, für das Erreichen der wirtschaftlichen Unternehmensziele essenziellen Nutzergruppen verwendet wird. Ist das der Fall, hilft Maximierung der MTTF nicht weiter, da Fehler weder vorhersehbar noch vermeidbar sind. Aber wie stellt man Hochverfügbarkeit in solchen verteilten Anwendungslandschaften sicher?

Mit Blick auf den zweiten Ansatz bleibt noch, MTTR, also den Zeitraum von der Erkennung (Detection) bis zur abschließenden Behebung (Recovery) oder zumindest Eindämmung beziehungsweise Linderung (Mitigation) zu minimieren. Abschließend ist die Ursache des Fehlers zu beheben und über ein Update in der letzten Phase (Treatment) des Fehlerlebenszyklus zu entfernen. Somit werden Schaden und Auswirkungen verringert und minimiert.

Positiv ausgedrückt, hält das System oder der Baustein ein vorab spezifiziertes Leistungsniveau auch bei auftretenden Fehlern aufrecht. Aus der Perspektive des Nutzers merkt dieser im besten Fall überhaupt nicht, dass ein Fehler aufgetreten ist. Im schlechtesten Fall erhält der Nutzer mindestens eine reduzierte/"herabgesetzte" und definierte Serviceleistung ('graceful degradation of service'). Gar keine Reaktion sowie technische Meldungen wie "NullPointerException" oder "Service unavailable" sind für den Anwender wenig hilfreich, sondern wirken abschreckend. Das Mindeste ist eine aussagekräftige Meldung, wie es für den Anwender weitergeht, zum Beispiel: "Der Service ist aufgrund von ... aktuell nicht verfügbar, bitte versuchen Sie es in 5 Minuten noch einmal". Der Rest gehört ins Log.

Fehler sind zur Laufzeit in der Produktion zu verdecken, einzudämmen (keine weitere Auswirkungen und Ausbreitung auf die anderen Systeme) und zu beheben. Im Idealfall erfolgt diese Behandlung automatisch. Sind Anwendungen und Bausteine widerstandsfähig gegenüber Fehlern von innen und Störungen von außen, wird typischerweise von Fehlertoleranz ('fault tolerance') gesprochen.

Im Kontext der Fehlertoleranz muss man sich bewusst sein, ob es um die Stabilisierung der Datenqualität oder die Aufrechterhaltung der Prozessqualität geht. Viele technische Diskussionen erörtern vor allem, ob und wie die Konsistenz, die Verfügbarkeit oder die Partitionstoleranz der Daten sichergestellt werden soll. Dem Nutzer dagegen geht es meistens darum, sein Anliegen und damit den erforderlichen Prozess erfolgreich abzuschließen, die Datenqualität spielt dabei für ihn eine untergeordnete Rolle.

Für beide Zielsetzungen gibt es Muster, die die Zeiträume der genannten Phasen der MTTR verkürzen. Als zwei grundlegende Muster für Fehlertoleranz werden im Folgenden Isolation und Redundanz als gute Ausgangspunkte für fehlertolerante Systeme vorgestellt.