Das schwächste Glied: Wie verkettete Abhängigkeiten das Systemrisiko beeinflussen
Bei der Bewertung von Systemrisikoszenarien ist es sehr leicht, „verkettete“ Abhängigkeiten zu übersehen. Wir sind darauf trainiert, das Risiko auf „Knotenebene“ zu betrachten und zu fragen: „Wie wahrscheinlich ist es, dass dieses eine Element ausfällt.“ Doch das Systemrisiko ist weitaus komplizierter als das.
In den meisten Systemen gibt es einige Komponenten, die auf andere Komponenten angewiesen sind. Am häufigsten betrachten wir dies bei der Auslegung von Speicher für Server, doch es tritt bei jedem Systemdesign auf. Ein weiteres gutes Beispiel ist die Tatsache, dass Webanwendungen sowohl Anwendungshosts als auch Datenbankhosts benötigen, um zu funktionieren.
Verkettete Abhängigkeiten lassen sich am einfachsten anhand eines Beispiels erläutern. Wir werden ein übliches Virtualisierungsdesign mit SAN-Speicher betrachten, um zu verstehen, wo die Grenzen von Fehlerdomänen verlaufen, wo verkettete Abhängigkeiten bestehen und welche Rolle Redundanz bei der Risikominderung auf Systemebene spielt.
In einem üblichen SAN-Design (Storage Area Network) für die Virtualisierung verfügen Sie über Virtualisierungshosts (die wir der Einfachheit halber als die „Server“ bezeichnen), SAN-Switches (Switches, die dem Speichernetzwerk gewidmet sind) und die Disk-Arrays selbst. Jede dieser drei „Schichten“ ist von den anderen abhängig, damit das System als Ganzes funktioniert. Hätten wir den denkbar einfachsten Aufbau mit einem Server, einem Switch und einem Disk-Array, so hätten wir ganz offensichtlich drei Geräte, die drei eigenständige Ausfallpunkte darstellen. Der Ausfall eines einzigen der drei führt zum Ausfall des gesamten Systems. Kein einzelnes Element ist für sich allein nützlich. Dies ist eine verkettete Abhängigkeit, und die Kette ist nur so stark wie ihr schwächstes Glied.
In unserem vereinfachten Beispiel stellt jedes Gerät eine Fehlerdomäne dar. Wir können das Risiko mindern, indem wir die Zuverlässigkeit jeder Domäne verbessern. Wir können einen zweiten Server hinzufügen und auf der Virtualisierungsschicht eine Strategie für Hochverfügbarkeit oder Fehlertoleranz umsetzen, um das Risiko eines Serverausfalls zu verringern. Dies verbessert die Zuverlässigkeit einer Fehlerdomäne, lässt jedoch zwei unangetastet, die ebenso risikobehaftet sind wie zuvor. Anschließend können wir die Switching-Schicht angehen, indem wir einen redundanten Switch hinzufügen und eine Multipathing-Strategie konfigurieren, um den Ausfall eines einzelnen Switching-Pfades aufzufangen und so das Risiko auf dieser Schicht zu verringern. Nun wurden zwei Fehlerdomänen angegangen. Schließlich müssen wir die Speicher-Fehlerdomäne angehen, was auf ähnliche Weise geschieht, indem Redundanz durch ein zweites Disk-Array hinzugefügt wird, das auf das erste gespiegelt wird und im Falle eines Ausfalls transparent übernehmen kann.
Nachdem wir nun unser System aufgerüstet haben, verfügen wir noch immer über drei Fehlerdomänen in einer Abhängigkeitskette. Was wir getan haben, ist, jedes „Glied“ der Kette, jede Fehlerdomäne, für sich genommen besonders widerstandsfähig zu machen. Doch die Kette besteht weiterhin. Das bedeutet, dass das System als Ganzes weit weniger zuverlässig ist als jede einzelne Fehlerdomäne innerhalb der Kette für sich allein. Wir haben etwas weitaus Besseres geschaffen als das, womit wir begonnen haben, doch wir haben noch immer viele Fehlerdomänen. Diese Risiken summieren sich.
Was die Bestimmung des Gesamtrisikos schwierig macht, ist, dass wir das Risiko jedes Elements bewerten, dann das neue Risiko nach der Minderung (durch das Hinzufügen von Redundanz) bestimmen und anschließend das kumulative Risiko jeder der Fehlerdomänen gemeinsam in einer Kette ermitteln müssen, um das Gesamtrisiko des gesamten Systems zu bestimmen. Es ist äußerst schwierig, das Risiko innerhalb jeder Fehlerdomäne zu bestimmen, da die Art der Risikominderung eine bedeutende Rolle spielt. Beispielsweise kann ein Cluster aus Speicher-Disk-Arrays, das zu langsam übernimmt, zu einem Ausfall des Gesamtsystems führen, selbst wenn der Speichercluster selbst ordnungsgemäß funktioniert zu haben scheint. Schon die klare Definition eines Ausfalls kann daher eine Herausforderung darstellen.
Es ist oft verlockend, eine Risikobewertung aus der „Vogelperspektive“ vorzunehmen, was sehr gefährlich, aber bei Menschen, die nicht regelmäßig mit Risikobewertung befasst sind, sehr verbreitet ist. Die Tendenz besteht hier darin, das Risiko nur unter Betrachtung der „obersten“ Fehlerdomäne zu betrachten – im Allgemeinen die Server in einem Fall wie diesem – und sämtliche Risiken zu ignorieren, die unterhalb dieses Punktes liegen, indem man sie als „unter der Haube“ befindlich betrachtet und nicht als Teil der Risikobewertung. Es ist leicht, die technischeren, weniger exponierten und schlechter verstandenen Komponenten wie Netzwerk und Speicher zu ignorieren und sich auf die vergleichsweise leicht verständlichen und stark beworbenen Zuverlässigkeitsaspekte der obersten Schicht zu konzentrieren. Diese „Vogelperspektive“ bedeutet, dass die Risiken unterhalb der obersten Ebene verschleiert und im Allgemeinen ignoriert werden, was zu einem hohen Risiko ohne ein gutes Verständnis des Warum führt.
Das Verständnis des Konzepts verketteter Abhängigkeiten erklärt, warum komplexe Systeme, selbst mit komplexen Strategien zur Risikominderung, oft weitaus fragiler ausfallen als einfachere Systeme. In unserem obigen Beispiel könnten wir mehrere Dinge tun, um die Kette zu „verkürzen“, was zu einem insgesamt zuverlässigeren System führt.
Die offensichtlichste Komponente, die sich verkürzen lässt, ist die Netzwerk-Fehlerdomäne. Würden wir die Switches vollständig entfernen und den Speicher direkt mit den Servern verbinden (was natürlich nicht immer möglich ist), so würden wir damit faktisch eine ganze Fehlerdomäne beseitigen und ein Glied aus unserer Kette entfernen. Nun hätten wir statt drei Ketten, von denen jede ein gewisses Ausfallpotenzial hat, nur noch zwei. Einfacher ist besser, wenn alle übrigen Umstände gleich sind.
Wir könnten theoretisch auch die Speicher-Fehlerdomäne verkürzen, indem wir von externem Speicher zur Nutzung von Speicher lokal auf den Servern selbst übergehen, was uns im Grunde von zwei Fehlerdomänen auf eine einzige Fehlerdomäne bringt – die eine verbleibende Domäne trägt nun natürlich mehr Komplexität als vor der Verkürzung, doch die Gesamtkomplexität des Systems ist erheblich reduziert. Auch dies gilt unter der Voraussetzung, dass alle übrigen Faktoren gleich bleiben.
Ein weiterer Ansatz, den es zu erwägen gilt, besteht darin, einzelne Knoten für sich genommen zuverlässiger zu machen. Es ist heute in Mode, größere Systeme zu betrachten und die Risikominderung auf diese Weise anzugehen, indem redundante, kostengünstige Knoten hinzugefügt werden, um Fehlerdomänen zuverlässiger zu machen. Doch traditionell war dies nicht der Standardweg zur Zuverlässigkeit. In der Vergangenheit war es weitaus üblicher, wie die einstige Verbreitung von Mainframes und ähnlich klassifizierten Systemen zeigt, ein hohes Maß an Zuverlässigkeit in einen einzelnen Knoten einzubauen. Mainframes und High-End-Speichersysteme etwa tun dies bis heute. Dies kann tatsächlich ein äußerst wirksamer Ansatz sein, doch er deckt viele Szenarien nicht ab und ist im Allgemeinen äußerst kostspielig, oft verstärkt durch die Notwendigkeit, Systeme teilweise oder sogar vollständig vom Anbieter warten zu lassen. Dies geht in der Regel nur unter besonderen Nischenbedingungen auf und ist in einem allgemeineren Rahmen nicht praktikabel.
In jedem System dieser Art haben wir somit drei zentrale Strategien zur Risikominderung zu erwägen: die Zuverlässigkeit eines einzelnen Knotens zu verbessern, die Zuverlässigkeit einer einzelnen Domäne zu verbessern oder die Anzahl der Fehlerdomänen (Glieder) in der Abhängigkeitskette zu verringern. Diese in vernünftiger Weise zusammenzuführen, kann uns helfen, das für unser Geschäftsszenario angemessene Maß an Risikominderung zu erreichen.
Wo die wahre Schwierigkeit besteht und bestehen bleiben wird, ist der Vergleich unterschiedlicher Strategien zur Risikominderung. Das Risiko eines einzelnen Knotens lässt sich im Allgemeinen mit einem gewissen Maß an Zuversicht abschätzen. Eine Redundanzstrategie innerhalb einer einzelnen Domäne lässt sich weit weniger gut abschätzen – manche Redundanzstrategien sind hochwirksam und schaffen äußerst zuverlässige Fehlerdomänen, während andere sogar nach hinten losgehen und die Zuverlässigkeit einer Domäne verringern können! Die Komplexität, die mit Redundanzstrategien oft einhergeht, ist niemals ohne Vorbehalt, und obwohl sie sich typischerweise auszahlt, trägt sie selten das Maß an Zuverlässigkeitsgewinn, das anfänglich erwartet wird. Das Risiko einer Abhängigkeitskette abzuschätzen, ist daher umso schwieriger, da es ein klares Verständnis der mit jeder einzelnen Fehlerdomäne verbundenen Risiken erfordert sowie ein Verständnis der Ausfallgelegenheit, die an den Domänengrenzen besteht (wie der zuvor erwähnte Ausfall durch die Verzögerung beim Speicher-Failover).
Lassen Sie uns die Fragen rund um die Bestimmung des Risikos bei zwei sehr verbreiteten Herangehensweisen an dasselbe Szenario erkunden, aufbauend auf dem, was wir oben erörtert haben.
Zwei extreme Beispiele derselben Situation, die wir erörtert haben, sind ein einzelner Server mit internem Speicher, der zum Hosten virtueller Maschinen genutzt wird, gegenüber einer „Kette“ aus sechs Geräten mit zwei Servern und einer Hochverfügbarkeitslösung auf der Serverschicht, zwei Switches mit Redundanz auf der Switching-Schicht und zwei Disk-Arrays, die Hochverfügbarkeit auf der Speicherschicht bereitstellen. Wenn wir hier irgendeinen großen Faktor verändern, können wir im Allgemeinen eine recht klare Abschätzung des relativen Risikos liefern – wenn etwa einer der Fehlerdomänen eine zuverlässige Redundanz fehlt –, dann können wir recht klar bestimmen, dass der einzelne Server das insgesamt zuverlässigere System ist, außer in Fällen, in denen einem einzelnen Knoten ein extremes Maß an Einzelknoten-Zuverlässigkeit zugewiesen wird, was finanziell im Allgemeinen eine unpraktische Strategie ist. Doch wenn jede Fehlerdomäne Redundanz aufweist, sind wir gezwungen, die relativen Risiken der domäneninternen Zuverlässigkeit (die redundante Kette) gegenüber der domänenübergreifenden Zuverlässigkeit (die verkürzte Kette, der einzelne Server) zu vergleichen.
Bei den beiden gänzlich unterschiedlichen Herangehensweisen gibt es keine vernünftige Möglichkeit, die vergleichenden Risiken der beiden Mittel zur Risikominderung zu bewerten. Es ist allgemein anerkannt, dass die Herangehensweise mit sechs (oder mehr) Knoten und umfangreicher domäneninterner Risikominderung die zuverlässigere der beiden Herangehensweisen ist, und das ist mit nahezu absoluter Sicherheit im Allgemeinen zutreffend. Doch es ist nicht immer zutreffend, und nur selten übertrifft diese Herangehensweise die Einzelknotenstrategie um eine wahrhaft bedeutende Spanne, während sie häufig das Vier- bis Zehnfache der Einzelserverstrategie kostet. Das sind potenziell sehr hohe Kosten für einen wahrscheinlich geringen Zuwachs an Zuverlässigkeit und ein geringes potenzielles Risiko einer Einbuße an Zuverlässigkeit. Jedes zusätzliche Stück Redundanz fügt Komplexität hinzu, die ein Mensch implementieren, überwachen und warten muss, und mit Komplexität und menschlicher Interaktion geht immer mehr Risiko einher. Menschliche Fehler zu vermeiden, kann oft wichtiger sein als mechanische Ausfälle zu vermeiden.
Wir müssen außerdem die Kosten der Wiederherstellung berücksichtigen. Sollte es zu einem Ausfall kommen, ist es im Allgemeinen trivial, sich vom Ausfall eines einfachen Systems zu erholen. Ein äußerst komplexes System kann, nachdem es ausgefallen ist, ein hohes Maß an Aufwand erfordern, um es wieder in einen funktionsfähigen Zustand zu versetzen. Komplexe Systeme erfordern zudem ein weitaus breiteres und tieferes Maß an Erfahrung und Selbstsicherheit, um sie zu warten.
Es gibt keine einfache Antwort auf die Bestimmung der Zuverlässigkeit von Systemen. Moderne Systeme zur Informationsbereitstellung sind schlicht zu groß und zu komplex und weisen zu viele unbestimmbare Faktoren auf, um in allen Fällen bewertet werden zu können. Mit einem guten Verständnis verketteter Abhängigkeiten jedoch und einem Verständnis von Strategien zur Risikominderung können wir praktische Schritte unternehmen, um grob die relativen Risikoniveaus zu bestimmen, zu erkennen, wie ähnliche Risikoszenarien im Kostenvergleich abschneiden, Schwachstellen zu identifizieren, Fehlerdomänen und Abhängigkeitsketten zu erkennen und nachzuvollziehen, wie Änderungen am Systemdesign uns klar in Richtung oder weg von Zuverlässigkeit bewegen werden.
