- Die Knight Capital Group, einst ein zentraler Akteur im US-Aktienhandel, geriet am 1. August 2012 durch ein fehlgeschlagenes SMARS-Deployment an den Rand des Bankrotts und verlor in nur 45 Minuten 460 Millionen US-Dollar
- Ausgangspunkt des Vorfalls war, dass bei der Reaktion auf das Retail Liquidity Program der NYSE ein Flag des seit 8 Jahren ungenutzten Power-Peg-Codes für eine neue Funktion wiederverwendet wurde
- Der neue Code wurde nur auf 7 der 8 Server ausgerollt; als der verbliebene Server neue RLP-Orders erhielt, wurde die stillgelegte Power-Peg-Funktion erneut ausgeführt
- Power Peg leitete fortlaufend Child Orders weiter, ohne die Ausführungsmenge der Parent Order zu verfolgen, und Knight musste die Ursache in der Produktionsumgebung ohne Kill Switch und ohne dokumentiertes Reaktionsverfahren suchen
- Deployment ist genauso wichtig wie das Schreiben und Testen von Code, und ein Deployment, das auf manuellen Abläufen beruht, wird ohne Automatisierung, Wiederholbarkeit und Verifikation zu einem gravierenden Betriebsrisiko
Ein Hochfrequenzhandelsunternehmen bricht in 45 Minuten zusammen
- Knight Capital Group war ein US-Finanzdienstleister für Market Making, elektronische Ausführung sowie institutionellen Vertrieb und Handel
- 2012 war Knight mit jeweils rund 17 % Marktanteil an NYSE- und NASDAQ-gehandelten US-Aktien einer der größten Trader
- Knights Electronic Trading Group (ETG) verwaltete durchschnittlich mehr als 3,3 Milliarden gehandelten Stücke pro Tag und handelte täglich über 21 Milliarden US-Dollar
- Am 31. Juli 2012 verfügte Knight über rund 365 Millionen US-Dollar an liquiden Mitteln und Zahlungsmitteläquivalenten
SMARS-Update für die RLP-Unterstützung
- Die NYSE plante den Start des Retail Liquidity Program am 1. August 2012
- Knight aktualisierte dafür SMARS, einen automatisierten Hochgeschwindigkeits-Algorithmus-Router, der Orders an den Markt sendet
- SMARS war ein System, das „Parent Orders“ von der Handelsplattform entgegennahm und zur Ausführung in eine oder mehrere „Child Orders“ aufteilte
- Je größer die Parent Order, desto mehr Child Orders wurden erzeugt
- Dieses Update sollte den seit 8 Jahren ungenutzten Power-Peg-Code ersetzen
- Der neue Code verwendete das bisherige Flag zur Aktivierung von Power Peg für die neue Funktion erneut
- Der Code selbst war ausreichend getestet worden, und sein korrektes Verhalten war bestätigt
Ein fehlender Server beim manuellen Deployment
- Knight verteilte die neue Software vom 27. bis 31. Juli 2012 manuell und pro Tag nur auf eine begrenzte Anzahl von Servern; Ziel waren insgesamt 8 Server
- Laut SEC-Unterlagen kopierte ein Techniker den neuen Code nicht auf einen der 8 SMARS-Server
- Es gab weder ein Verfahren, bei dem ein zweiter Techniker dieses Deployment prüfte, noch ein dokumentiertes Verfahren, das eine solche Prüfung verlangte
- Infolgedessen wurde auf dem 8. Server weder der Power-Peg-Code entfernt noch der neue RLP-Code hinzugefügt
Wie toter Code wieder zum Leben erwachte
- Als der Markt am 1. August 2012 um 9:30 Uhr (US-Ostküstenzeit) öffnete, begann Knight, Orders von Broker-Dealer-Kunden für das Retail Liquidity Program zu verarbeiten
- Die 7 korrekt ausgerollten Server verarbeiteten die Orders normal
- Orders, die auf dem 8. Server landeten, aktivierten über das wiederverwendete Flag erneut den alten Power-Peg-Code
- Power Peg war ursprünglich dafür zuständig, bei der Ausführung von Child Orders die im Verhältnis zur Parent Order gekauften oder verkauften Aktien zu zählen und das Routing weiterer Child Orders zu stoppen, sobald die Parent Order erfüllt war
- Knight hatte 2005 die kumulative Verfolgung an eine frühere Stelle im Codeablauf verlagert, sodass die Aggregationsverfolgung innerhalb von Power Peg entfernt worden war
- Als auf dem 8. Server das Power-Peg-Flag aktiviert wurde, routete Power Peg Child Orders an Ausführungsmärkte, verfolgte aber die Stückzahl gegenüber der Parent Order nicht mehr und verhielt sich dadurch faktisch wie eine Endlosschleife
Warnsignale vor der Eröffnung und Eskalation nach 9:30
- Das Knight-System begann an diesem Tag ab 8:01 Uhr automatisch E-Mails zu versenden
- Sie wurden ausgelöst, wenn SMARS Orders für den vorbörslichen Handel verarbeitete
- Die E-Mails erwähnten SMARS und kennzeichneten den Fehler als „Power Peg disabled“
- Von 8:01 bis 9:30 wurden 97 solcher E-Mails an Knight-Mitarbeiter gesendet
- Diese E-Mails waren nicht als Systemalarm konzipiert und wurden daher nicht sofort bemerkt
- Unmittelbar nach der Markteröffnung um 9:30 bemerkten mehrere Personen an der Wall Street die Anomalie
- Um 9:31 war klar, dass etwas Schwerwiegendes geschah, und um 9:32 wurde immer drängender die Frage, warum es nicht stoppte
- In den ersten 45 Minuten machten Knights Ausführungen bei einigen Titeln mehr als 50 % des Handelsvolumens aus und trieben bestimmte Aktienkurse um mehr als 10 % nach oben
- In Reaktion auf die fehlerhaften Trades verloren andere Aktien an Wert
Fehlender Kill Switch und falsche Reaktion
- Knight verfügte über keinen Kill Switch, um das betroffene System sofort zu stoppen
- Es gab auch kein dokumentiertes Reaktionsverfahren, sodass die Ursache in einer Produktionsumgebung diagnostiziert werden musste, in der pro Minute 8 Millionen Aktien gehandelt wurden
- Da Knight die Ursache nicht fand, entfernte das Unternehmen den neuen Code von den korrekt ausgerollten Servern
- Diese Maßnahme entfernte den funktionierenden Code und ließ den fehlerhaften Code bestehen
- Danach aktivierten zusätzliche Parent Orders den Power-Peg-Code nicht mehr nur auf einem, sondern auf allen Servern, wodurch sich das Problem verschärfte
- Erst nach 45 Minuten konnte Knight das System stoppen
Ausmaß des Verlusts und das Ende des Unternehmens
- In den ersten 45 Minuten nach der Markteröffnung verarbeitete der Power-Peg-Code 212 Parent Orders
- SMARS sendete Millionen von Child Orders an den Markt; dadurch entstanden letztlich 4 Millionen Trades in 154 Titeln und ein Handelsvolumen von mehr als 397 Millionen Aktien
- Knight übernahm in 80 Titeln eine Netto-Long-Position von rund 3,5 Milliarden US-Dollar und in 74 Titeln eine Netto-Short-Position von rund 3,15 Milliarden US-Dollar
- Die Knight Capital Group realisierte in 45 Minuten einen Verlust von 460 Millionen US-Dollar
- Da die liquiden Mittel und Zahlungsmitteläquivalente zu diesem Zeitpunkt 365 Millionen US-Dollar betrugen, fiel Knight vom größten US-Aktienhändler und bedeutenden Market Maker faktisch in die Insolvenz
- Um den Verlust auszugleichen, musste innerhalb von 48 Stunden Kapital beschafft werden; Knight erhielt schließlich 400 Millionen US-Dollar Investment von etwa 6 Investoren
- Später wurde die Knight Capital Group im Dezember 2012 von Getco LLC übernommen; das fusionierte Unternehmen wurde zu KCG Holdings
Lehren für DevOps und Continuous Delivery
- Es reicht nicht aus, nur gute Software zu entwickeln und zu testen
- Damit Kunden Wert erhalten, muss Software korrekt ausgerollt werden
- Die Ursache des Vorfalls lag nicht nur bei dem einen Engineer, der SMARS ausrollte, sondern darin, dass Knights Prozesse dem offengelegten Risiko nicht gewachsen waren
- Ein Deployment, das davon abhängt, dass Menschen Anweisungen lesen und befolgen, birgt immer die Möglichkeit von Fehlern
- Fehler können in der Anweisung selbst, in ihrer Interpretation oder in ihrer Ausführung entstehen
- Deployments sollten so weit wie möglich automatisiert und wiederholbar sein, um die Möglichkeit menschlicher Fehler zu verringern
- Hätte ein automatisiertes Deployment-System Konfigurations-, Deployment- und Testautomatisierung umfasst, wäre der Fehler, der Knightmare auslöste, wahrscheinlich vermeidbar gewesen
- Von den Prinzipien der Continuous Delivery sind in diesem Fall besonders zwei relevant
- Software-Releases sollten ein wiederholbarer und verlässlicher Prozess sein
- Es sollte in vernünftigem Rahmen so viel wie möglich automatisiert werden
1 Kommentare
Hacker-News-Kommentare
Ich bin mir nicht sicher, wie automatische Deployments dieses Problem gelöst hätten. Wahrscheinlich hätten sie eher die Auswirkungen und Nachwirkungen noch vergrößert.
Ersetzt man „ein Entwickler hat vergessen, Code auf einen Server zu spielen“ durch „der Deployment-Agent hatte beim Herunterladen eines neuen Binary/Codes auf den Server einen Fehler, und wegen eines Bugs im Agent wurde dieser Fehler nicht sichtbar“, erhält man denselben Failure Mode. Die Auswirkungen hätten sich nur schneller verbreitet.
Die Verantwortung liegt hier beim Entwickler. Denn der Code wurde auf nicht abwärtskompatible Weise geschrieben.
Sowohl der Markt als auch Knight wussten, dass es ein schwerwiegendes Problem gab, trotzdem wurden 45 Minuten lang mehrere Hotfixes versucht, bevor der Handel gestoppt wurde. Entweder gab es keinen Kill Switch, oder niemand hatte die Befugnis, ihn zu betätigen, weil ein Druck zum falschen Zeitpunkt etwa 500.000 Dollar an Opportunitätskosten verursachen konnte.
Ich arbeitete damals bei einem Wettbewerber von Knight. Auch wir deployten häufig schreckliche Bugs in die Produktionsumgebung, aber bei Post-Mortems war schwer vorstellbar, dass uns dasselbe passieren könnte. Es gab mehrere automatische Systeme, die einzelne Trades verhinderten, und ein Senior Trader oder Operations-Verantwortlicher konnte nach einem 60-Sekunden-Gespräch den Kill Switch ziehen, ohne die Folgen fürchten zu müssen.
Tatsächlich hätten wir an Knights Verlust von 400 Millionen Dollar sogar noch mehr verdienen können, aber unser Risikosystem kam zu dem Schluss, dass es „zu gut war, um wahr zu sein“, und schaltete die Strategie immer wieder ab, wodurch der Gewinn sank.
Man muss sich den Teil „Ein Techniker von Knight kopierte den neuen Code nicht auf einen der acht SMARS-Server“ noch einmal ansehen. Natürlich kann auch eine CI/CD-Pipeline unterwegs fehlschlagen und nur auf einigen Servern deployen, aber ich halte das für unwahrscheinlich.
Selbst wenn das passiert wäre, hätte ein Ansible Playbook beim Moment dieses Übertragungsfehlers angehalten, und das gesamte Playbook wäre fehlgeschlagen; es wäre gar nicht bis zum letzten Schritt, dem Neustart des Dienstes, gekommen.
Das war menschliches Versagen, und genau deshalb gibt es Automatisierung.
Auch der Teil „ein zweiter Techniker prüfte das Deployment nicht, niemand bemerkte, dass auf dem achten Server der Power-Peg-Code nicht entfernt und der neue RLP-Code nicht hinzugefügt worden war“ hätte durch CI/CD verhindert werden können. Ein „Pull Request“ auf das Ansible-Code-Repository hätte verhindert, dass der erste Techniker ohne Review in master/main mergt. master/main muss schließlich geschützt sein.
Ich bin überzeugt, dass DevOps auf Basis von CI/CD dieses Problem zu 100 % gelöst hätte.
Charity Majors hat bei der Euruko viel dazu gesagt. Deployment-Tools sollten nicht bloß Bash-Skripte im Mantel sein, sondern ausreichend Personal und Tests haben und so weit wie möglich durchautomatisiert sein.
Ein Deployment-Prozess, der einer unveränderlichen Architektur nahekommt, Tools zur Überwachung fehlgeschlagener/gestoppter/unvollständiger Rollouts und die Fähigkeit, schnell zu einem zuvor funktionierenden Zustand zurückzukehren, schaffen Verteidigungsschichten und erleichtern den Handlungsweg, wenn etwas schiefläuft. Dieses Problem wäre dadurch nicht unmöglich geworden, aber es wäre schwieriger gewesen, dass es überhaupt auftritt.
Eine manuelle Ausführungsanleitung wird bei jeder Serverarbeit zu einem Ratespiel nach dem Motto: „Ich habe Schritt 12 gemacht, ich glaube auch Schritt 13, also kommt jetzt Schritt 14.“ Das menschliche Gehirn kann, wenn eine millionenfach ausgeführte Tätigkeit mittendrin unterbrochen wird, die aktuelle Ausführung oft nicht zuverlässig von falschen Erinnerungen aus früheren Durchläufen unterscheiden.
Ohne Interlocks, die das Überspringen von Schritten verhindern, ist es jedes Mal ein Glücksspiel. Und der Aufwand, solche Interlocks zu bauen, macht bereits einen erheblichen Teil der Automatisierungskosten aus.
„Warum Code, der acht Jahre lang tot war, noch in der Codebase blieb, ist ein Rätsel, aber das ist nicht der Kernpunkt“, hieß es – für mich scheint genau das der Kernpunkt zu sein
Offenbar ließ man acht Jahre lang ungenutzten Code einfach liegen und wollte ihn erst entfernen, als man das Flag wiederverwenden wollte. Hätte man es vor acht Jahren richtig gemacht und den ungenutzten Code gelöscht, wäre die Geschichte ganz anders verlaufen. Keine alte Routine wäre wiederauferstanden, und es hätte keinen eigenmächtigen Server gegeben
Vielleicht nutzte Knight Capital keine Versionsverwaltung und hielt den Code „für alle Fälle“ fest. Aber ich habe auch in vollständig versionierten Repositories Entwickler gesehen, die Code nicht löschen wollten, und das ist wirklich erstaunlich. Wenn man ihn wieder braucht, holt man ihn aus der Versionsverwaltung zurück. Wenn man ihn wieder braucht, aber vergessen hat, dass er dort ist, hätte man den toten Codepfad genauso wenig gefunden. Ihn im Source Tree zu lassen, ist reine Schuld
Kevlin Henney hat bei GOTO einen hervorragenden Vortrag über Software-Zuverlässigkeit gehalten und behandelt diesen Punkt am Beispiel von Knight Capital. Tatsächlich zitiert er auch diesen Blogpost https://youtu.be/IiGXq3yY70o?si=hZ9HB2dlfj0vHvNK&t=463
„Es gibt keinen wirklich toten Code. Eine kleine Annahme, eine Änderung einer Annahme, und plötzlich ist es kein toter Code mehr, sondern Zombie-Code. Eine wiederauferstandene Zombie-Apokalypse kostet Geld“
git logdie Historie ansehen und vielleichtgit blameverwenden können – ungefähr dasOft wissen sie nicht, wie man die Git-Historie filtert. Sie kennen weder
git pickaxenoch Exclude-Patterns und kommen nicht einmal auf die Idee, dass man mit etwas wiegit log -G'int.*foo\\(' -- ':(exclude)directory'in den Git-Logs nachfoosuchen kann, während man ein bestimmtes Verzeichnis ausschließtStattdessen wissen sie, wie man im aktuellen Code Tree
grepbenutzt. Also denken sie, wenn man den Code nicht löscht, kann man ihn mit dem passendengrepwiederfinden. Wenn er gelöscht ist, wissen sie womöglich nicht, wie sie ihn in der Git-Historie finden sollenBis zu einem gewissen Grad ist das nachvollziehbar. Code in Git-Logs ist für viele Tools unsichtbar. Zum Beispiel schlägt ihn der Editor nicht per Autocomplete vor, und er taucht auch nicht in der Bibliotheksdokumentation auf
Wenn man wirklich glaubt, dass dieser Code wiederverwendet wird, lässt sich einigermaßen verteidigen, ihn im Tree zu behalten, damit er Refactorings mitmacht und bei Bedarf auffindbar ist. In Fällen wie Knight Capital, wo er offensichtlich nie wieder gebraucht werden würde, ist das aber schwer zu rechtfertigen
Selbst ein Update, das lediglich „alten Code entfernt“, kann für jemanden schwierig wirken, der jede Änderung als Risiko sieht, etwas kaputtzumachen. Fairerweise ist jede Änderung ein Risiko, aber alten Code liegen zu lassen ist ebenfalls ein Risiko
Immerhin kann man nun auf diesen Fall als klares Beispiel für das Risiko verweisen
Was ich an dieser Geschichte jedes Mal wirklich nicht verstehe, ist, dass man ein bestehendes Flag wiederverwendet hat, statt ein neues Flag anzulegen. Warum hat man das getan?
git rebasefür immer verschwindenIch hoffe, die meisten Organisationen haben Prozesse, die so etwas rund um den Main Branch verhindern. Aber ich habe in einer kleinen Organisation selbst einmal versehentlich eine Produktionsdatenbanktabelle ruiniert, daher würde ich auch ein versehentliches
git rebasenicht für unmöglich haltenEs gab ein weiteres Problem mit einer Datenbank, die nur 256 Spalten hatte. Wenn eine neue Spalte gebraucht wurde, nutzte man einfach eine alte Spalte wieder, die „damals nicht verwendet“ wurde
Wenn ich mich richtig erinnere, galt das intern im Allgemeinen ebenfalls als „schlechte Idee“, aber niemand priorisierte es, alten Code aufzuräumen oder bessere Best Practices einzuführen
Kein Continuous-Deployment-System, das ich erlebt habe, hätte diesen konkreten Bug verhindert
Es war zwar ein schrittweiser Rollout, aber im Code steckte ein Logikfehler, bei dem ein einziger fehlgeschlagener Installationsschritt während dieses schrittweisen Rollouts das Unternehmen in die Insolvenz treiben konnte
Um das zu verhindern, hätte man zur Laufzeit prüfen müssen, ob die Softwareversionen, etwa die Git-SHAs, übereinstimmen, und zusätzlich Fault Injection in Tests einbauen müssen, die die Software-Rollout-Infrastruktur aufrufen
Es war der komplette Wilde Westen. Wichtig ist auch, dass sich Handelssysteme seitdem stark verändert haben
Als ich 2009 in diesem Bereich anfing, war die Systemzuverlässigkeit bei Banken, Brokern und Börsen ziemlich chaotisch. Es kam oft vor, dass man telefonisch bestätigen musste, wie hoch die ausgeführte Menge war
Ich erinnere mich an die Zeit, als die italienische Börse ein System ausrollte. Irgendwann wurde in einer Umgebung „getestet“, die aus Produktion und UAT vermischt war, und wenn ich mich richtig erinnere, änderte man nach Handelsschluss nur die IP der Order-Entry-Verbindung, um das nächste Release zu testen. Die UAT-Umgebung war zu verbuggt und größtenteils halbtot, sodass man dort nicht testen konnte
Von Excel-Tabellen mit VBA-Code, über den selbst ChatGPT fluchen würde, die Produkte mit Handelsvolumina mit lauter Nullen bepreisten, fangen wir gar nicht erst an
Heute ist das ganz anders. Auch dank solcher Vorfälle. Das meiste ist automatisiert, und die Cowboy-Haltung ist deutlich seltener geworden
Es gibt verpflichtende Kill Switches, mehrere Schichten von Risiko- und Handelsaktivitätsüberwachung sowie Überwachung auf Börsenseite, und in die Systeme sind wirklich viele hart gelernte Lektionen eingeflossen. Das ist auch ein Grund, warum Leute die Schwierigkeit, ein gutes Handelssystem zu bauen, naiv einschätzen. Die Strategien sind zwar klüger geworden, aber im Kern geht es meist darum, nicht an etwas außerhalb der normalen Bedingungen zu sterben
In der quantitativen Finanzwelt kennt buchstäblich jeder Knight Capital. Es gibt sogar den Ausdruck „pulling a knight capital“. Er bedeutet, dass man selbst bei mission-critical Systems, die ein Unternehmen in kürzester Zeit in die Insolvenz treiben können, Abkürzungen nimmt und dafür den Preis zahlt
Das System unseres Teams spielt eine wichtige Rolle für Umsätze in Höhe von Hunderten Millionen Dollar pro Tag. Wenn das System lange genug ausfällt, verschwindet dieser Umsatz. „Lange genug“ heißt hier mindestens ein paar Stunden, und innerhalb dieses Zeitraums kann man es in der Regel ohne allzu große externe Auswirkungen wieder in den Normalzustand bringen.
Wir haben ebenfalls manuelle Prozesse, aber bei jedem manuellen Prozess dokumentieren wir vorab die Rollback-Prozedur und überwachen das Deployment. Außerdem trennen wir Code-Deployment und Feature-Deployment; Feature-Deployments erfolgen schrittweise hinter Feature-Flags.
Für neue Features oder Codeänderungen verlangen wir neue Feature-Flags. Das ist schmerzhaft und langsam, hat uns aber geholfen, gefährliche Situationen und Panik zu vermeiden, und hat die Belastung durch Betrieb und On-Call deutlich reduziert.
Damit wirklich etwas katastrophal schiefgeht, muss es mehrere „Fehlerfilter“ passieren: Im Code-Review wird eine Verhaltensänderung ohne Feature-Flag übersehen, manuelle Tests bzw. Tests in der Entwicklungsumgebung übersehen sie ebenfalls, das Deployment schlägt fehl, der Rollback schlägt fehl oder ist falsch, es gibt kein Monitoring, das meldet, dass das Problem noch nicht behoben ist, es wird nicht rechtzeitig an höhere Ebenen eskaliert, und nach genügend Zeit verliert man die Fähigkeit, das SLA einzuhalten.
Bei riskanteren manuellen Änderungen kann man auch zwei Personen gemeinsam ändern lassen: Eine Person geht per Videoanruf durch, was geändert wird, die andere verifiziert es.
Wenn man mit Systemen arbeitet, deren SLA im Minutenbereich liegt und deren Änderungen nicht rückgängig zu machen sind, muss man einen praktikablen Weg kennen, innerhalb weniger Minuten zu überwachen und zurückzurollen. Wenn es eine neue, manuelle Aufgabe ist, sollte man sie vierfach prüfen und eine andere Person daneben zusehen lassen. Andernfalls ist es nur eine Frage der Zeit, bis mehrere Probleme nacheinander zusammenkommen und ein nicht mehr behebbarer Moment entsteht. Egal wie talentiert und klug Menschen sind: Wenn sie manuell Änderungen vornehmen oder Änderungen anstoßen müssen, passieren immer Fehler, und die Wahrscheinlichkeit solcher Fehler muss in den Change-Management-Prozess eingebaut sein.
Im normalen Handel oder im B2B können Kunden in vielen Fällen denselben Kauf kurz darauf erneut versuchen. Es ist nicht „jetzt oder nie“.
Ich habe auch schon Dinge, die ich kaufen wollte, später erneut versucht, wenn der Verkäufer down war, die Server wegen einer neuen Ankündigung und hoher Nachfrage zusammengebrochen waren oder es ein Problem mit einer Bankenwartung gab.
Verwandte Beiträge:
Knightmare: A DevOps Cautionary Tale (2014) - https://news.ycombinator.com/item?id=22250847 - Februar 2020, 33 Kommentare
Knightmare: A DevOps Cautionary Tale (2014) - https://news.ycombinator.com/item?id=8994701 - Februar 2015, 85 Kommentare
Knightmare: A DevOps Cautionary Tale - https://news.ycombinator.com/item?id=7652036 - April 2014, 60 Kommentare
Außerdem:
The $440M software error at Knight Capital (2019) - https://news.ycombinator.com/item?id=31239033 - Mai 2022, 172 Kommentare
Bugs in trading software cost Knight Capital $440M - https://news.ycombinator.com/item?id=4329495 - August 2012, 1 Kommentar
Knight Capital Says Trading Glitch Cost It $440 Million - https://news.ycombinator.com/item?id=4329101 - August 2012, 90 Kommentare
Gibt es noch weitere?
Nanex ~ 03-Aug-2012 ~ The Knightmare Explaned - https://news.ycombinator.com/item?id=4337359 - keine Kommentare
Das eigentliche Problem war, wenn man die Formulierung im Stil von „kein wahrer Schotte“ einmal gelten lässt, dass eine Kombination aus ungetesteter Konfiguration und Binary-Release verwendet wurde.
Konfiguration und Binary können abgestimmt gleichzeitig ausgerollt werden, und so lässt sich diese Art von Problem verhindern. Natürlich gab es auch andere Fehler, aber ohne diese Bedingung hätte dieses Problem nicht auftreten können.
Die Stelle „Es ist ein Rätsel, warum Code, der acht Jahre lang tot war, noch in der Codebase war, aber das ist nicht der Kernpunkt“ beschreibt vielleicht nicht den schlimmsten Fehler in der Geschichte, aber man kann auch nicht sagen, dass sie nicht zentral sei.
Hätte man die tote Funktion proaktiv entfernt, wäre die Software einfacher und besser verständlich gewesen, und die Wahrscheinlichkeit eines Durchgehens wäre geringer gewesen. Ohne solche Wartung ständig nur voranzuschreiten, ist — ob kalkuliert oder nicht — ein Risiko.
Ich bin wirklich froh, keinen Code zu schreiben, der ohne menschliches Eingreifen automatisch Millionen von Dollar routet.
Das wirkt, als würde man Code schreiben, der Jumbojets fliegt. Wer möchte so eine Verantwortung tragen?
Ich sehe das als eine Aufgabe für einen bestimmten Typ Mensch, der Prozesse, Tests, Simulatoren und Redundanz liebt. Der Code, der das Flugzeug fliegt, ist dabei nur 1 % des Engineerings.
Man geht die Sorgen, die einem natürlich in den Sinn kommen, eine nach der anderen an; je rationaler man sich Sorgen macht, desto besser ist es fürs Geschäft. Aus meiner Erfahrung im Finanzsektor war Knights Problem zu 10 % ein technisches Problem und zu 90 % das Problem, dass jemand wie ein CTO Kühnheit mit Kompetenz verwechselte — nicht nur an diesem Tag oder in jener Woche, sondern insgesamt.
Zu einem gewissen Grad dürfte das auch an diesem Vorfall liegen.