Ein Albtraum wurde wahr – Erfahrungen eines versierten Rails Entwicklers

Ich schreibe dieses, um mir selber Luft zu verschaffen und weil ich denke, man kann aus Vorfällen, wie ich sie hier erlebt habe auch als alter Hase noch viel lernen.

Stell Dir vor: Du bist für eine komplexe Software allein verantwortlich.  Du musst im laufenden Betrieb neue, für das System grundlegend neue Features einführen.  Du hast die neuen Features über „Feature Schalter“ langsam in das System gebracht.  Viele benutzen bereits erfolgreich die neuen Features.  Jetzt ist der Zeitpunkt gekommen, wo du anfangen kannst, alte Features abzuschalten und alle Benutzer mehr oder weniger zwangsweise auf die neuen Features zu führen.  Das ist wahrscheinlich der schwierigste Moment einer Produkteinführung.  Es gibt kein einfaches Zurück mehr.  Just in diesem Moment passiert das, wovor sich alle Entwickler und Systemadministratoren immer fürchten.  Das System stirbt und es gibt einen kompletten Datenverlust für mehrere Tage.

Das genau passierte bei der UlangoTV 2.0 Einführung.

Das ganze ist so beispielhaft und klassisch, dass ich denke, es wird viele unter den technisch Versierten interessieren, wie es dazu kommen konnte und wie man sich einigermassen ohne Schaden aus einer solchen Katastrophe befreien kann.

Ein Fataler Crash mit großen Datenverlusten – wie kann es dazu kommen?

Die meisten Web- und App-Server benutzen heutzutage Linux-Systeme, weil die sich über Jahre schon als besonders stabil, sicher, leistungsfähig und dazu noch günstig herausgestellt haben – so auch wir.  Viele Administratoren sind stolz darauf, dass ihre Systeme bereits länger 6 oder mehr Monaten nicht mehr neu gestartet werden mussten und einfach stabil ihren Dienst machen.  Es werden regelmässig Backups gemacht – heute meistens von den Providern per Snapshot auf der untersten Ebene der rohen Partitionen.   Dazu werden regelmässige DB Backups mit den Werkzeugen der DB gemacht, weil diese die notwendige Transaktionssicherheit garantieren.

Die DB Backups sind dabei ein besonderes Problem, wenn die Datenbanken wie in unserem Fall zu gross werden – über 50GB.   Das Einspielen solcher Datenmengen erfordert sehr viel Zeit und führt zu grosser Downtime im Katastrophenfall.   Einziger Ausweg zum Erreichen einer hohen Verfügbarkeit ist das Einbringen von Redundanz.  Wie uns das in unserem Fall geholfen hat relativ schnell wieder auf die Beine zu kommen, dazu unten mehr.

Nun zum Absturz selber.  Im laufenden Betrieb bei zunehmend größerer Systemlast kommt es plötzlich dazu, dass einige Prozesse mit ihrer Arbeit nicht mehr fertig werden.  Die Last schwillt an, das System fängt an zu swappen bis praktisch nichts mehr geht.  Schnell werden Lastverursacher identifiziert, Services werden runtergefahren. Aber plötzlich hilft auch das nicht mehr, weil es offensichtlich eine Blockadesituation im System gibt (A wartet auf B, B wartet auf C, C wartet auf A – deadlock – ihr wisst was ich meine).  Ganz schlimm, wenn die Blockade offensichtlich ganz unten im Filesystem liegt.  Jetzt ist der Moment gekommen, wo nur noch ein Neustart Abhilfe schaffen kann.  Und da passiert es:  Das System lässt sich nicht mehr booten, weil es Inkonsistenzen im Filesystem gibt.  Das ist in der Regel nicht weiter schlimm, weil ein modernes Filesystem genügend Redundanz in sich trägt um sich selbst zu reparieren.   Leider war aber auch das in unserem Fall nicht mehr möglich.  Keine Chance, das System wieder lauffähig zu machen.  Also muss ein Backup eingespielt werden – vom letzten Tag – wenige Stunden zuvor.   Nach einer Stunde stellen wir fest, dass auch hier das Filesystem bereits zu kaputt ist, dass es nicht mehr nutzbar ist.  Noch ein Backup zurück – wieder eine Stunde – geht auch nicht. Jetzt wird’s langsam kritisch.   Wir bereiten in der Zwischenzeit ein neues System vor, in das wir unseren Backup einspielen – Upload der komprimierten Daten: 22 Stunden!!

Also noch ein Backup zurück – das wöchentliche Backup 5 Tage zurück.  Hurrah – es geht.  Ich entscheide mich, auf das Einspielen der DB zu verzichten und mit dem Datenverlust von 5 Tagen irgendwie zurechtzukommen. Puh.

Restaurierung von Daten aus redundanten Quellen

Wenn es darum geht, nach einem Datenverlust möglichst schnell wieder zu einem aktuellen konsistenten Zustand zu kommen, können Quellen aller Art helfen.   Hier kommt die Mächtigkeit der von uns verwendeten Programmiersprache Ruby on Rails zum tragen, mit deren Hilfe sehr schnell AdHoc-Programme geschrieben werden konnten.   Wir hatten in unserem Fall drei Quellen: 1. Zentrale Logfiles, die auf anderen Servern redundant abgelegt waren.  2. Unsere externen Bestelldaten bei PayPal und 3. unser Riak-basierter Key-Value Speicher für Channels und Streams.

Aus den Logfiles war es relativ einfach, Benutzerdaten – bis auf die Passwörter natürlich-  wieder herzustellen. Mit einem AdHoc Programm wurden die Daten eingespielt und die User per email benachrichtigt, ihre Passwörter zurückzusetzen.

Das Restaurieren der Bestelldaten gestaltete sich als wesentlich schwieriger, da die zugehörigen Bestell-Informationen auch verloren gegangen waren und nicht in allen Fällen eine Zuordnung der Zahlungen zu Benutzern hergestellt werden konnte.

Schliesslich relativ einfach war das Wiederherstellen unsere zentralen Datenbank für Streams und Channels. Diese Daten hatten wir schon vor längerer Zeit in einen sog. Key-Value Store (Riak) überführt, insbesondere um neben der erreichten Redundanz über mehrere Server auch die Last bei Anfragen zu verteilen.  Es ist der Schlüssel zu einem praktisch unbegrenzt skalierbaren System.   Es ist eine Technik, die heute bei allen großen Systemen genutzt wird und erstmals von Amazon in größerem Stil eingesetzt wurde (Dynamo).

Fazit

Für uns bleiben im wesentlichen folgende Schlussfolgerungen

  1. Häufigeres Neustarten des Systems um „schleichende“ Zerstörung von Daten, die dann auch in die Backups wandert, frühzeitig zu erkennen.
  2. Ablage der DB Backups nah am Server um diese möglichst schnell verfügbar zu haben.
  3. Bessere Zusammenführung der Logs (Syslog Daemon)
  4. Noch mehr Daten – insbesondere Benutzer und Bestelldaten in verteilte KV-Stores verlagern um die „Single Point of Failure“ Situationen zu minimieren.

So – das bin ich jetzt los geworden und ich fühle mich viel besser und bereit, neuer Herausforderungen anzugehen!

Facebooktwittergoogle_pluspinterestlinkedinmail

Dieser Beitrag ist auch verfügbar auf: Englisch

2 Kommentare zu “Ein Albtraum wurde wahr – Erfahrungen eines versierten Rails Entwicklers

  1. Hallo Herr Dr. Ullrich! Zunächst möchte ich mich bedanken, dass Sie so viel Zeit in Ulango-TV investieren. Dann ist es umso mehr ärgerlich, wenn es auch noch zu einem Server-Crash kommt. Aber ich finde es klasse dass Sie uns, also die User von Ulango-TV, detailiert über diesen Server-Crash informieren. Da könnten sich viele Appentwickler ein Beispiel nehmen – Respekt!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.