Über die zufällige Komplexität von supply chain Systemen
Moderne computing hardware ist extrem leistungsfähig. Ein bescheidenes Smartphone liefert Milliarden von FLOPS (floating point operations per second), während es Hunderte von Gigabyte an Daten speichert. Ein einzelnes Smartphone könnte technically eine prädiktive inventory allocation für ein sehr großes Einzelhandelsnetzwerk ausführen. Die historischen Daten würden eine geeignete Darstellung1 erfordern und auf der Seite der Datenverarbeitung müssten schlankere Techniken wie differentiable programming eingesetzt werden. Daher sollten hochleistungsfähige supply chain Systeme selbstverständlich sein. Sicherlich können es sich Unternehmen leisten, etwas Besseres als ein Smartphone einzusetzen, um ihre supply chains zu betreiben und zu optimieren. Doch eine beiläufige Beobachtung der supply chain Systeme unserer Kunden bei Lokad zeigt genau das Gegenteil: Diese Systeme sind fast immer langsam und häufig torturously so.

Moderne supply chain software Vorreiter (ERP, WMS, MRP etc.) haben Schwierigkeiten, selbst 1 Anfrage pro Sekunde auf ihrem API-Backend aufrechtzuerhalten. Bei Lokad werden wir täglich schmerzlich an solche entsetzlichen Leistungen erinnert, da wir an vorderster Front des data retrieval Prozesses stehen. Bei etwa einem Dutzend Kunden dauerte die anfängliche Datenerfassung fast einen Monat2. Die Trägheit der verschiedenen APIs ist für 99,9% des Problems verantwortlich. Systeme, die 1MB/second bei ihrer data extraction aufrechterhalten können, sind rar. Systeme, die uns nicht zwingen, dieselben Daten immer und immer wieder unnötig neu zu extrahieren – um die aktuellsten Teile zu erreichen – sind noch seltener. Diese Systeme verfügen typischerweise über 100+ mehr Rechenressourcen als noch vor 2 Jahrzehnten, und dennoch sind sie grundsätzlich weder schneller3 noch leisten sie radikal bessere Arbeit. Einige der fortschrittlichsten Anbieter, die in-memory computing nutzen, benötigen mehrere Terabyte RAM, um mit Einzelhandelsnetzwerken umzugehen, was angesichts dessen, was mit diesen Ressourcen gemacht wird, eine erschreckend große4 Menge an RAM darstellt.
Diese „accidental complexity“ vieler (meist?) supply chain Systeme lässt sich auf zwei Hauptursachen zurückführen: erstens falsche Erwartungen an den Fortschritt der Rechenhardware selbst, zweitens mangelnde Sorgfalt bei der internen Gestaltung der Lösung.
Was den Fortschritt der Rechenhardware betrifft, gab es vor einem Jahrzehnt noch kein einziges (großes) Unternehmen, in dem das erste Moore’s law nicht bereits dutzende Male (meist fehlerhaft) angepriesen wurde. Man hatte den Eindruck, dass Computer ständig lächerlich schneller wurden. Leider hörte dies größtenteils auf, trivially wahr zu sein, seit den frühen 2000er Jahren. Diese falsche Auffassung eines unendlichen Fortschritts führte dazu, dass viele Softwareunternehmen – weit über den supply chain Bereich hinaus – massive Fehler machten. Viele der mit Windows Vista (2006 veröffentlicht) verbundenen Probleme konnten auf die ursprünglichen Erwartungen – bereits 2001, als Windows XP veröffentlicht wurde – der Microsoft-Ingenieure zurückgeführt werden, dass CPUs bis 2006 mit 6Ghz getaktet sein würden. Wir nähern uns dem Ende des Jahres 2020, und High-End-Gaming-CPUs kommen kaum an 5Ghz heran. Die Rechenhardware hört nie auf, Fortschritte zu machen; jedoch hörte sie – zumindest aus Sicht der Softwareunternehmen – auf, in trivialer Weise fortzuschreiten.
In den 1980er und 1990er Jahren war es selbstverständlich, dass sobald eine Software funktionierte, selbst wenn sie zum Veröffentlichungszeitpunkt etwas langsam war, im nächsten Jahr eine anständige Geschwindigkeit erreicht würde und im darauffolgenden Jahr eine ausgezeichnete Leistung erzielt würde. Aggressive Softwareunternehmen wie Microsoft spielten diese Karte sehr gut: Ihren Ingenieuren wurde (werden immer noch) die beste Rechenhardware zur Verfügung gestellt, die man für Geld kaufen kann, und systematisch wurde die Softwareleistung bis an die Grenze des Akzeptablen ausgereizt, in dem Wissen, dass die Hardware das Leistungsproblem im Wesentlichen nach ein oder zwei Jahren lösen würde. Nach dem Vista-Debakel erkannten die Engineering-Teams bei Microsoft das Ausmaß des Problems und änderten ihre Vorgehensweise – Windows 7 war dabei eine erhebliche Verbesserung. Dennoch dauerte es ein Jahrzehnt, bis sich Windows in puncto Leistung wirklich erholte. Heutzutage ist der Ausblick nahezu das genaue Gegenteil: Die besten Teams bei Microsoft setzen nicht mehr auf zukünftige Hardware, sondern konzentrieren sich nahezu ausschließlich darauf, sofort überlegene Leistung durch überlegene Software5 zu liefern.
Die Welt der Unternehmenssoftware stellte sich jedoch als weitaus träger heraus, das Problem zu erkennen, und baute während der 2010er Jahre Software, als stünde die zukünftige Rechenhardware kurz davor, all ihre Probleme zu lösen, wie es in der Vergangenheit bereits mehrfach der Fall war. Leider, für die meisten Anbieter von Unternehmenssoftware, obwohl die Rechenhardware weiterhin Fortschritte macht, hörte sie vor einem Jahrzehnt auf, in trivialer Weise fortzuschreiten6, sodass der Anbieter sich einfach auf die Leistungssteigerung verlassen konnte. Software neigt dazu, im Laufe der Zeit Ballast anzuhäufen (mehr Funktionen, mehr Optionen, mehr Bildschirme etc.). Daher ist es eine natürliche Tendenz komplexer Software, im Laufe der Zeit langsamer zu werden, anstatt sich zu verbessern – es sei denn, es wird ein intensiver, gezielter Aufwand in diesem Bereich betrieben.
Leider ist Leistung aus Vertriebsperspektive meist ein Nebenschauplatz. Demos werden mit Spielerkonten durchgeführt, die nur einen verschwindend kleinen Bruchteil der Datenlast enthalten, mit der das System in der Produktion konfrontiert wäre. Außerdem erhalten Bildschirme, die für das Top-Management von Interesse sind, einen unverhältnismäßig hohen Grad an Ausarbeitung im Vergleich zu jenen, die für die einfachen Mitarbeiter bestimmt sind. Doch genau diese Bildschirme werden tausende Male pro Tag genutzt und sollten daher die meiste Aufmerksamkeit erhalten. Ich vermute, dass APIs häufig eine schlechte Leistung bieten, weil nur wenige Käufer prüfen, ob die APIs tatsächlich eine Leistung erbringen, die mit ihrem vorgesehenen Zweck übereinstimmt. Softwareanbieter wissen das und passen ihre Investitionen in die Technik entsprechend an.
Dies führt mich zum zweiten Aspekt des Leistungsproblems: dem mangelnden Augenmerk auf das interne Design der Lösung. Derzeit bedarf es strategischer Software-Design-Entscheidungen, um den Großteil der fortlaufenden Hardware-Verbesserungen auszuschöpfen. Eine Designentscheidung ist jedoch ein zweischneidiges Schwert: Sie befähigt, aber sie begrenzt auch. Es erfordert starke Führung, sowohl auf der geschäftlichen als auch auf der technischen Seite, sich zu einer Designentscheidung zu bekennen. Unentschlossenheit ist einfacher, aber im Nachteil leidet – wie die überwiegende Mehrheit der Unternehmenssoftware zeigt – die Leistung (und die UX im Allgemeinen) erheblich.
Eine Falle moderner Software (und nicht nur der Unternehmenssoftware) ist die Überfülle an Schichten. Daten werden kopiert, weitergeleitet, gesammelt, synchronisiert, … durch Dutzende innerer Schichten innerhalb der Software. Infolgedessen wird der Großteil der Rechenressourcen für die „interne plumbing“ verschwendet, die an sich keinen Mehrwert liefert. Bezüglich des Designs ist die Abhilfe sowohl einfach zu konzipieren als auch schwer umzusetzen: Man muss einen sparsamen Einsatz von Drittanbieter-Komponenten vornehmen, insbesondere jener Komponenten, die eine Art Schicht beinhalten7. Aus der Sicht eines Softwareanbieters ist das Hinzufügen einer weiteren Schicht der schnellste Weg, um dem Produkt mehr „cool features“ hinzuzufügen, ganz zu schweigen vom Ballast.
Bei Lokad haben wir uns für einen umfassend integrierten Stack entschieden, indem wir unsere gesamte Plattform um einen Compiler-Kern entworfen haben. Nachteilhaft daran ist, dass wir die Möglichkeit verlieren, ein beliebiges Open-Source-Projekt problemlos in unser Design einzubinden. Integrationen bleiben möglich, erfordern aber in der Regel tiefgreifendere Änderungen am Compiler selbst. Auf der positiven Seite erreichen wir „bare metal“ Performance, die in Bezug auf Unternehmenssoftware normalerweise als unthinkable gilt. Insgesamt hat sich dieser Ansatz, angesichts der Tatsache, dass Open-Source-Komponenten schlecht altern, in den letzten zehn Jahren als besonders effektiv erwiesen8.
Gemeinsam genutzte multi-tenancy ist eine weitere Designentscheidung, die die Leistung radikal beeinflusst, zumindest aus der Perspektive des Verhältnisses von Preis zu Leistung („bang for the buck“). Die meiste Unternehmenssoftware – supply chain software eingeschlossen – hat stark schwankende Anforderungen an die Rechenressourcen. Zum Beispiel gibt es am extremen Ende des Spektrums die forecasting numerical recipe, die nur einmal am Tag (oder so) ausgeführt wird, aber jedes Mal die gesamten historischen Daten verarbeiten muss every single time. Ein statischer Satz an Rechenressourcen9, der einem Kunden zugeordnet ist, ist höchst ineffizient.
Auch bei Lokad haben wir uns für eine vollständig mutualisierte Infrastruktur entschieden. Dieser Ansatz senkt unsere Cloud-Betriebskosten, während er eine Leistung liefert, die andernfalls wirtschaftlich nicht tragbar wäre (Cloud-Kosten würden die supply chain Vorteile überwiegen). Um eine reibungslose Gesamtkoordination aller Arbeitslasten zu gewährleisten, haben wir einen hohen Grad an „Vorhersehbarkeit“ für unseren eigenen Verbrauch von Rechenressourcen entwickelt. Lokads DSL (domänenspezifische Programmiersprache), namens Envision, wurde dafür entwickelt, dieses Vorhaben zu unterstützen. Aus diesem Grund existieren in Envision ganze Klassen von Programmierkonstrukten – wie willkürliche Schleifen – nicht, da diese Konstrukte nicht mit den Anforderungen an eine hohe Vorhersehbarkeit kompatibel sind, die das data crunching in supply chains mit sich bringt.
Abschließend: Erwarten Sie nicht, dass ein aufgeblähtes supply chain System in absehbarer Zeit fit wird, wenn es nicht bereits fit ist. Obwohl die Rechenhardware noch Fortschritte macht, ist sie bereits sehr schnell. Wenn das System träge ist, liegt das höchstwahrscheinlich daran, dass es seiner zugrunde liegenden Hardware entgegenarbeitet – und nicht daran, dass es an Hardware mangelt. Das Problem zu beheben ist möglich, aber es ist hauptsächlich eine Frage des Designs. Leider ist das grundlegende Software-Design eines der Dinge, die in der Unternehmenssoftware nach der Designphase des Produkts nahezu unmöglich zu beheben sind. Es ist jedoch möglich, sich zu erholen, wie Microsoft gezeigt hat, aber nicht jedes Unternehmen (sowohl Anbieter als auch Kunde) kann sich das Jahrzehnt leisten, das dafür benötigt wird.
-
Bereits 2012 veröffentlichte ich ReceiptStream, ein kleines Open-Source-Projekt, um zu demonstrieren, dass es nicht nur machbar ist, etwa ein Jahr an Walmart-Transaktionshistorie auf Korbebene auf einer SD-Karte zu speichern, sondern dass es auch mit nur wenigen hundert Zeilen Code realisiert werden kann. ↩︎
-
Wir versuchen, eine inkrementelle Datenerfassung durchzuführen, wenn es die Systeme zulassen. Doch in der Regel reicht die anfängliche Datenerfassung 3 bis 5 Jahre zurück, da ein wenig historische Tiefe wirklich hilft, wenn es um Saisonanalysen geht. ↩︎
-
Konsolenterminals mögen veraltet aussehen, aber wenn diese Systeme über mehrere Jahrzehnte hinweg funktionierten, bedeutet das, dass sie vermutlich einige ausgleichende Qualitäten besaßen, wie etwa niedrige Latenzzeiten. Es gibt nichts Ärgerlicheres, als ein modern gestaltetes Webinterface, bei dem jede Seitenaktualisierung mehrere Sekunden dauert. ↩︎
-
Ich sage nicht, dass Terabyte an RAM bei der supply chain Optimierung nicht nützlich sein könnten – ich wiederhole nur das fiktive Zitat, das fälschlicherweise Bill Gates zugeschrieben wird, dass „640K ought to be enough for anybody“. Mein Punkt ist, dass ein übermäßiger Einsatz von Rechenressourcen eine vergeudete Gelegenheit ist, sie besser zu nutzen. Stand Dezember 2020 sehe ich keinen Grund, warum eine derart große Menge an Speicher erforderlich sein sollte, wenn man die (geringe) Raffinesse der numerischen Rezepte im sogenannten „in-memory computing“ Paradigma berücksichtigt. ↩︎
-
Die leistungsgesteigerten Verbesserungen, die nahezu ausschließlich softwaregetrieben durch .NET Core 1, .NET Core 2, .NET Core 3 und .NET 5 erzielt wurden, sind in dieser Hinsicht beispielhaft. Einige Geschwindigkeitssteigerungen beruhen auf SIMD-Anweisungen (single instruction, multiple data), jedoch qualifizieren sich diese Anweisungen kaum als „future“ Hardware, da die meisten in den letzten zehn Jahren verkauften CPUs diese Fähigkeiten bereits besitzen. ↩︎
-
Hardware-Schwachstellen such as Meltdown erwiesen sich als nachteilig für die Leistung der bestehenden Rechenhardware. Ähnliche Probleme sind in Zukunft zu erwarten. ↩︎
-
Schichten gibt es in allen Formen und Gestalten. Docker, HDFS, Python, NumPy, Pandas, TensorFlow, Postgres, Jupyter … sind allesamt Komponenten von höchstem Interesse, und dennoch führt jede dieser Komponenten eine eigene Software-Schicht ein. ↩︎
-
Als ich 2008 Lokad gründete, entschied ich mich, meine eigene Forecasting-Engine zu entwickeln. Damals war R in aller Munde. 2012 war es Hadoop. 2014 waren es Python und SciPy. 2016 war es Scikit. 2018 war es TensorFlow. 2020 ist es Julia. ↩︎
-
Der Lackmustest, um zu erkennen, ob ein angeblich SaaS (Software as a Service) eine mutualisierte multitenant Architektur nutzt, besteht darin, zu prüfen, ob es möglich ist, sich für eine Art kostenloses Konto zu registrieren. Wenn der Anbieter kein kostenloses Konto bereitstellen kann, ist es nahezu sicher, dass der Anbieter lediglich ASP (Application Service Provider) statt SaaS betreibt. ↩︎