Spark

Junior

Warum ist mein Spark-Job plötzlich langsamer geworden, ohne Code-Änderungen?

Neun von zehn Mal liegt es nicht am Code. Es liegt an den Daten, am Cluster oder an einer Konfiguration, die still aufgehört hat, zu beidem zu passen.

Lesen auf:
Daten wuchsen, Config nicht Join nicht mehr balanciert Cluster-Config driftete
Grob geordnet nach Häufigkeit der tatsächlichen Ursache — nicht über einen echten Datensatz gemessen.

Sie haben den Job nicht angefasst. Der DAG ist identisch. Das letzte Deployment liegt drei Wochen zurück. Und trotzdem hat der Lauf letzte Nacht 40 Minuten statt 12 gedauert. Das ist eines der häufigsten Tickets im Data Engineering, und es lässt sich fast immer auf eine von drei Ursachen zurückführen.

1. Die Daten sind gewachsen, die Konfiguration nicht

Shuffle-Partition-Anzahl, Executor-Speicher und Broadcast-Join-Schwellenwerte werden meist einmal, während der ursprünglichen Entwicklung, gegen das damals vorhandene Datenvolumen festgelegt. Sechs Monate später hat dieselbe Tabelle die vierfache Zeilenzahl, und dasselbe spark.sql.shuffle.partitions=200 erzeugt jetzt Partitionen, die nicht mehr bequem in den Speicher passen und bei jedem Shuffle-Stage auf Festplatte ausweichen. Am Code hat sich nichts geändert — an der Annahme, die die Konfiguration kodiert hat, schon.

So prüfen Sie das: Vergleichen Sie Eingabe-Zeilenzahlen und Shuffle-Lese-/Schreibbytes zwischen einem aktuellen langsamen Lauf und einem älteren schnellen, im Stages-Tab der Spark-UI. Ein großer Sprung dort, mit einer ungefähr proportionalen Verlangsamung, deutet genau darauf hin.

2. Ein Join, der mal balanciert war, ist es nicht mehr

Data Skew kündigt sich nicht an — er bedeutet nur, dass eine Handvoll Partitionen das 10- bis 100-fache der Arbeit der übrigen übernehmen, sodass die Wanduhrzeit vom langsamsten Task diktiert wird, nicht vom durchschnittlichen. Eine Key-Verteilung, die beim Start ungefähr gleichmäßig war, kann driften, wenn sich Nutzungsmuster ändern (ein Kunde, eine Region, ein Ereignistyp beginnt, das Volumen zu dominieren).

So prüfen Sie das: Sortieren Sie in der Stage-Detailansicht der Spark-UI die Tasks nach Dauer. Ein Stage, bei dem der p50-Task 4 Sekunden und der maximale Task 6 Minuten braucht, ist eindeutig skewed.

3. Der Cluster ist nicht der Cluster, auf dem Sie getestet haben

Autoscaling-Cluster, Spot-Instance-Pools und geteilte Multi-Tenant-Cluster können Ihrem Job still weniger oder langsamere Executor geben als beim letzten Mal, besonders bei Konkurrenz durch andere Jobs. Das zeigt sich als langsamere Wanduhrzeit bei identischer Pro-Task-CPU-Zeit — der Job leistet dieselbe Arbeit, wartet nur länger auf Ressourcen dafür.

So prüfen Sie das: Vergleichen Sie die tatsächlich zugewiesenen (nicht angeforderten) Executor über Läufe hinweg, und schauen Sie sich die Scheduler-Verzögerung an, nicht nur die Task-Dauer.

Der schnellste Weg, das zu unterscheiden: Sie brauchen zwei Dinge nebeneinander — Ihre aktuelle Konfiguration und echte Metriken aus dem tatsächlich gelaufenen Run. Genau das ist die ganze Idee hinter der Regel-Engine von opti-pipe: Sie liest das tatsächliche Task-Timing, Shuffle-Volumen und den Speicherverbrauch aus Ihrem Event-Log und prüft es gegen Ihre konfigurierten Shuffle-Partitionen / Executor-Speicher / Instanzanzahl — statt dass Sie die Spark-UI anstarren und raten, welcher der drei obigen Punkte es ist.

Sehen Sie, wie das bei Ihrer eigenen Pipeline aussieht.

Laden Sie ein echtes Spark-Event-Log, ein dbt run_results.json oder einen Flink-Metrics-Export hoch und erhalten Sie konkrete, vor der Anwendung zu genehmigende Empfehlungen zurück — keine weitere Faustregel.