Zusammenfassung

  • Neue Kinesis-Frontends erzeugten auch auf den bestehenden Servern zusätzlichen Kommunikationsaufwand. Die Flotte überschritt eine vom Betriebssystem gesetzte Thread-Grenze und konnte ihre Routing-Informationen nicht mehr aufbauen.
  • Beim Neustart konkurrierte dieser Aufbau mit Kundenanfragen. Die vorhandenen Maschinen waren deshalb nicht sofort wieder nutzbare Kapazität.

Ein Cloud-Verkäufer kann die zusätzliche Maschine zählen. Schwieriger wird es, wenn er auch die zusätzliche Arbeit zählen soll, die sie allen anderen Maschinen macht.

Kinesis lieferte dafür am 25. November 2020 ein teures Anschauungsstück. AWS erweiterte in Nord-Virginia die Frontend-Kapazität in relativ kleinem Umfang. Danach überschritten sämtliche Frontend-Server eine Thread-Obergrenze ihrer Betriebssystemkonfiguration. Der offizielle Ereignisbericht trennt ausdrücklich den Auslöser vom Grundproblem. Die Erweiterung brachte eine schon in der Konstruktion steckende Skalierungsgrenze zum Vorschein.

Der Ausweg sollte unter anderem über stärkere Rechner führen, damit die Flotte insgesamt weniger Server benötigte. Weniger Maschinen bedeuteten weniger Kommunikationspartner pro Maschine. Eine Branche, die gern größere Stückzahlen verkauft, hatte plötzlich einen guten Grund für eine kleinere Teilnehmerliste.

Die zweite Rechnung jeder neuen Maschine

Kinesis verarbeitete Datenströme in Backend-Zellen. Die Frontends übernahmen Authentifizierung, Begrenzung und Weiterleitung der Anfragen. Sie mussten wissen, welche Backend-Gruppe welche Teile eines Datenstroms betreute. Dafür hielten sie eine lokale Zuordnung vor, die sogenannte Shard-Map.

Zu ihren Informationsquellen gehörten laufende Nachrichten der anderen Frontends. Jeder Server legte Betriebssystem-Threads für die Kommunikation mit den übrigen Mitgliedern an. Ein Neuzugang erhöhte also auch die Arbeit der bereits laufenden Server. Bis diese alle neuen Mitglieder entdeckten, konnte eine Stunde vergehen.

Damit war das Ende der Erweiterungsarbeiten kein verlässlicher Zeitpunkt für eine Entwarnung. Die zusätzliche Koordinationslast kam verteilt an. Als die Thread-Grenze erreicht war, wurden die Zuordnungen nicht mehr fertig aufgebaut. Ohne brauchbare Karte konnte das Frontend eine Anfrage nicht zum richtigen Backend schicken.

Die Zellen im Backend waren weiterhin eine sinnvolle Grenze. Sie begrenzten nur nicht automatisch die Koordination davor. Ein Käufer sollte bei einer zugesagten Isolation deshalb nach dem geteilten Bestandteil außerhalb der Kästchen fragen. Genau dort kann die Rechnung aller neuen Kästchen zusammenlaufen.

Neustart mit Einlasskontrolle

AWS nahm die zusätzliche Kapazität zurück. Die Betriebssystemgrenze ohne weitere Tests anzuheben, wollte das Team vermeiden. Anschließend mussten die Frontends neu starten.

Beim Wiederanlauf baute ein Server seine Karte auf und sollte zugleich Kundenanfragen bedienen. Beide Arbeiten beanspruchten dieselben Ressourcen. Zu viele gleichzeitig zurückkehrende Server konnten langsam werden, als ungesund gelten und wieder aus der Flotte fallen. Mehr Tempo beim Einschalten hätte weniger Fortschritt bei der Reparatur bedeuten können.

AWS änderte daher auch den Startvorgang: Informationen sollten direkt aus dem maßgeblichen Metadatenspeicher kommen, statt beim Hochfahren von Nachbarservern bezogen zu werden. Trotzdem ließen sich aus einer Flotte von vielen Tausend Servern nur wenige Hundert pro Stunde zurückführen. Die erste Gruppe nahm um 10:07 Uhr pazifischer Standardzeit wieder Verkehr an. Um 22:23 Uhr arbeitete Kinesis normal; während des Wiederanlaufs gingen die Fehlerraten schrittweise zurück.

Diese Stunden gehörten zur Kapazitätsrechnung. Die Maschinen waren vorhanden. Das System konnte sie nur nicht schneller in nutzbare Leistung verwandeln. Ein Einkauf, der ausschließlich die Leistung im eingeschwungenen Zustand betrachtet, lässt genau diese Umwandlung offen.

Die wirtschaftliche Bedeutung liegt im Zeitpunkt. Normalerweise kauft ein Unternehmen zusätzliche Leistung, weil es Arbeit zu erledigen hat. In einer Störung wächst der Druck weiter: neue Anfragen, liegen gebliebene Arbeit und das Wiederherstellen des Betriebszustands kommen gleichzeitig. Das ist ein anderer Lastfall als ein gewöhnlicher Leistungsnachweis.

Als die Hilfsarbeit die Hauptarbeit blockierte

Auch andere Dienste legten offen, wie teuer eine scheinbar nachgeordnete Abhängigkeit werden kann. Cognito sammelte über Kinesis Muster der API-Nutzung. Die Übermittlung war als bestmöglicher Versuch mit lokalem Puffer vorgesehen. Bei der langen Unterbrechung kam ein verborgener Fehler im Puffercode zum Tragen. Der Rückstau blockierte Webserver; Nutzer konnten sich teilweise nicht anmelden oder temporäre Zugangsdaten erhalten.

Der Puffer hatte zunächst Zeit gekauft. Erst sein Verhalten am Ende dieser Zeit bestimmte, ob die Anmeldung unabhängig weiterarbeiten konnte. Eine größer dimensionierte Warteschlange kann die Prüfung hinausschieben. Sie beantwortet sie noch nicht.

CloudWatch konnte Metriken und Protokolle nur eingeschränkt verarbeiten. Alarme wechselten teilweise in einen Zustand unzureichender Daten; reaktive Auto-Scaling-Regeln, die diese Metriken benötigten, reagierten verspätet. Bei Lambda wiederum verursachte das Puffern von Metriken Speicherkonkurrenz auf den Ausführungshosts und erhöhte die Fehlerquote.

Das reguläre Werkzeug zum Veröffentlichen des Dienststatus hing an Cognito. Ein weniger abhängiges Ersatzwerkzeug funktionierte, war aber manueller und den Beschäftigten weniger vertraut. Veröffentlichungen verzögerten sich. Eine technische Reserve muss auch organisatorisch einsatzbereit sein.

Was nach der Hardwarezahl kommt

AWS kündigte stärkere Server und damit weniger gegenseitige Verbindungen, feinere Thread-Alarme, Tests einer höheren Obergrenze und kürzere Kaltstarts an. Ein eigener Cache-Bestand, getrennte Frontends für einige große Dienste sowie schnellere Frontend-Zellbildung sollten die gemeinsam betroffene Fläche verkleinern. Das waren mehrere unterschiedliche Eingriffe in die Rechnung: weniger Koordinationsarbeit, mehr Reserve und kleinere Folgen eines Fehlers.

AWS beschreibt in seiner Erklärung zur statischen Stabilität Systeme, die bei beeinträchtigten Abhängigkeiten weiterarbeiten. Der Text zu Fehlertoleranz und Fehlerisolation nennt dabei auch die Kosten vorab bereitgestellter Reserve. Eine freie Maschine kostet Kapital. Eine erst während der Störung aktivierbare Maschine kostet zusätzlich Zeit, wenn ihre Aktivierung auf die gestörte Infrastruktur angewiesen ist.

Der historische Bericht enthält keine heutige Frontend-Grenze und keinen aktuellen vollständigen Neustarttest. Ein solcher Test mit offengelegten Bedingungen würde eine Beurteilung der gegenwärtigen Wiederanlaufleistung verändern. Der Maßstab aus dem Jahr 2020 bleibt handfest: Was macht der nächste Server mit den bereits laufenden Servern, und wie schnell können alle nach einem Fehler wieder arbeiten?