4 Punkte von GN⁺ 2025-12-09 | Noch keine Kommentare. | Auf WhatsApp teilen
  • Während der Migration der Codebasis von Scala 2.13 auf Scala 3 kam es zu unerwartetem Performance-Verlust
  • In Test- und Deployment-Umgebungen waren anfangs alle Metriken normal, aber nach einigen Stunden stieg der Kafka-Lag
  • Bei den Load Tests wurde ein Durchsatzabfall bei fein granularer Nachrichtenverarbeitung festgestellt
  • Durch die async-profiler-Analyse zeigte sich, dass ein Bug in der Kettenauswertung der Quicklens-Bibliothek die Ursache war
  • Nach dem Update der Bibliothek erholte sich die Leistung, was die Notwendigkeit unterstreicht, Leistungsunterschiede zwischen Scala-Versionen in Bibliotheken zu beachten

Migrationsprozess des Services

  • Der bestehende Service wurde von Scala 2.13 auf Scala 3.7.3 migriert
    • Es handelte sich um einen datensammelnden Service ohne Einsatz von Makros, bei dem Leistung eine kritische Komponente ist
    • Nach dem Anwenden von Abhängigkeits-, Compiler-Optionen sowie Typ- und Syntaxänderungen war der Compile erfolgreich
  • In Testumgebung und gestuftem Deployment wurden Logs und Metriken ebenfalls als normal gemeldet
    • Infrastruktur-, JVM- und Anwendungsebenen-Metriken wurden durchgehend als gesund eingestuft

Unklare Ursache der Leistungsabnahme

  • Etwa 5 bis 6 Stunden nach dem Rollout trat ein Anstieg des Kafka-Lags auf
    • Auch ohne Daten-Spikes sank die Verarbeitungsrate pro Instanz
    • Nach einem Rollback stieg die Durchsatzrate sofort wieder an, wodurch bestätigt wurde, dass die Codeänderung die Ursache war

Leistungsanalyse und Ursachenforschung

  • In den Lasttests ließ sich die Performance-Regressions initial nicht reproduzieren
    • Der Durchsatzabfall trat nur bei feingranularer Verarbeitung und heterogenen Payloads auf
  • Durch sequentielles Zurücksetzen abhängiger Bibliotheken (Serialization, DB SDK, Docker-Image, Konfigurationsbibliotheken usw.) ergaben sich keine Änderungen
  • Die CPU-Profilsanalyse mit async-profiler ergab, dass
    • in Scala 3 die CPU-Auslastung von JIT-Compiler und Decoding-Phase stark anstieg
    • im Flamegraph belegt ein Quicklens-Aufruf die Hälfte der gesamten CPU-Zeit
    • in Scala 2.13 machte derselbe Aufruf nur rund 0,5 % aus

Grundursache

  • In der Quicklens-Bibliothek trat in Scala 3 ein Bug mit ineffizienter Kettenauswertung auf
    • Die zugehörige Korrektur ist in GitHub PR #115 enthalten
    • Nach dem Update der Bibliothek wurde der Performance-Unterschied zwischen Scala 3 und 2.13 behoben

Lektionen und Empfehlungen

  • Eine metaprogrammierende Abhängigkeit von Bibliotheken kann zu Performance-Unterschieden zwischen Scala-Versionen führen
  • Auch wenn eine Migration erfolgreich abgeschlossen ist, sollten Hotspots und Engpässe benchmarked werden
  • In Leistungs-kritischen Services ist eine Validierung auf Basis realer Messdaten zwingend erforderlich, statt nur zu unterstellen, dass „es funktioniert“
  • Vorbeugende Checks sind erforderlich, um Situationen zu vermeiden, in denen der Benchmark statt des Codes den Engpass offenlegt

Noch keine Kommentare.

Noch keine Kommentare.