Förderjahr 2020 / Stipendien Call #15 / ProjektID: 5115 / Projekt: Improving Serverless Edge Computing for Network Bound Workloads
Simulation First! Eine Reihe von Umständen hat mich dazu gebracht die Reihenfolge, in der ich das Prorblem der Performance-Verbesserungen angehe zu ändern. Ursprünglich war geplant zunächst eine Methode zu entwickeln, diese dann praktisch zu testen, und letztlich auch größere Szenarien mit dieser Methode theoretisch zu evaluieren. Stattdessen habe ich direkt mit Simulationen in größeren Szenarien begonnen. Diese Entscheidung hatte eine Reihe an Gründen:
- Auch wenn Simulationen komplex sind, sind diese schneller und leichter anzupassen als echte Systeme. Das Erlaubt schnellere Iterationen und macht es daher einfacher unpassende Herangehensweisen zu identifizieren, und Kurs zu ändern.
- Simulationen laufen schneller als Echtzeit, und lassen sich parallelisieren. Eine Optimierngsmethode kann so beispielsweise in 10 unterschiedlichen Szenarien grob evaluiert werden, und das innerhalb von 30 Sekunden. Was hier 30 Sekunden dauert, bräuchte in einer Evaluierung auf echter Hardware wohl einen ganzen Tag oder mehr.
- Edge-Computing und insbesondere Serverless-Computing werden typischerweise für große und komplexe Deployments verwendet, daher ist die Evaluierung in großen Szenarien fast wichtiger als die in kleinen. Hierbei spielt auch hinein, dass Serverless hier eine Abstraktion über Edge-Computing sein soll und entsprechend weitreichende multi-tenant Szenarien zu erwarten sind.
- Die Interaktionen und das Verhalten von Systemen wird durch das einbinden "Intelligenter" Akteure sehr schnell komplex, und in Teilen unvorhersehbar. Dies hat sich bereits im letzten Blogeintrag gezeigt, als Traefik (der intelligente least response time load-balancer) keine stabile Gewichtsverteilung unter den Servern finden konnte, und zwischen unterschiedlichen Konfigurationen oszilliert ist.
Erste Simulationsergebnisse
Sobald ich die load-balancing methode, die ich bereits in der Anpassung von traefik verwendet habe im Simulator eingebaut hatte, bzw. den Simulator so angepasst habe, dass meine Experimente damit überhaupt möglich sind, hat sich die Entscheidung zuerst zu simulieren als richtig herausgestellt.
Im nächsten Blogeintrag werde ich darauf eingehen wie genau die ersten Experimente aufgebaut sind, und was die Ergebnisse hiervon sind. Diesen Eintrag möchte ich mit einem kleinen Exkurs in die Interaktionen beenden, die entstehen wenn so komplexe Systeme wie FaaS erweitert werden:
Im Simulator wie in der Realität sind FaaS Systeme auf bestehender Containertechnologie aufgebaut. Im Simulator, wie auch bei OpenFaaS (dem Framework welches ich benutze) ist das konkret Kubernetes. Eine Funktion ist also ein Container, und von jeder Funktion können mehrere Kopien, sogenannte Replicas, existieren. Es ist sogar typisch, dass eine Funktion mehrere Replicas hat, die auf unterschiedlichen Servern laufen um Ausfälle zu verhindern und viele Anfragen gleichzeitig zu beantworten. Wie viele Replicas eine Funktion hat kann sich mit der Zeit ändern, und hängt normalerweise davon ab wie viele gebraucht werden, was wiederum davon abhängt wie viele Anfragen ankommen. Der Teil des Systems, der dies überwacht und entscheidet wird "Scaler" genannt. Nun gibt unterschiedlichste Methoden nach denen der Scaler entscheiden kann wie viele Replicas existieren sollen. Eine Methode hierbei ist anzusehen wie viele Anfragen im Durchschnitt pro Replica gerade darauf warten bearbeitet zu werden. Wenn viele warten, werden neue Replicas erstellt, also mehr Rechenleistung für diese Funktion zur Verfügung gestellt. Hier kommt das unerwartete Verhalten ins Spiel: Der "intelligente" load-balancer schafft es die Anfragen effektiver zu verteilen, als der klassiche round-robin (verteilt die Anfragen immer gleichmäßig). Trotzdem ist die Gesamtperformance des intelligenten load-balancers in den Simulationen schlechter. Das wirkt doch absurd, nicht wahr? Hier kommt die Interaktion ins Spiel: Weil der intelligente load-balancer die Anfragen effizient und je nach Kapazität auf die Server verteilt, warten im Durchschnitt weniger Anfragen, und daher ist der Scaler hierbei nicht der Meinung, dass mehrere Replicas benötigt werden. Durch die Effiziente Verteilung hat das System also weniger Rechenleistung zur Verfügung, und ist insgesamt langsamer. Jetzt ist das intelligente System deshalb nicht schlechter oder falsch, und es ist definitiv sparsamer als das klassische. Aufgrund der vielen Teile im System die einander beeinflussen verhält es sich aber anders als man es intuitiv erwarten würde, was ich hier zeigen wollte. Dies muss nicht schlecht sein, denn es eröffnet schlicht mehr Möglichkeiten. In diesem Fall könnte man nun zwischen Ressourceneffizienz und Performance wählen, was vorher nicht möglich war. Diese ersten Beobachtungen, und man kann hier tatsächlich von Beobachtungen sprechen, liefern interessante Erkenntnisse bzw. bestärken bestehende Annahmen:
- Wenn ein Teil des Systems verändert wird, hat das wahrscheinlich Auswirkungen auf andere Teile, daher können die Teile nicht in Isolation betrachtet und verändert werden.
- Änderungen die intuitiv eine Verbesserung darstellen sollten, können im Endeffekt eine Verschlechterung sein, zumindest nach einer gewissen Metrik.
- Komplexeres Verhalten von Teilen des Systems eröffnet Flexibilität.