Spark SQL Diagnose
Wann verwenden
Verwenden Sie dieses Skill, wenn der Benutzer eine der folgenden Kombinationen bereitstellt:
- Eine Spark UI / History Server / YARN proxy URL;
- Eine Spark SQL und deren
EXPLAIN FORMATTED; - Kyuubi / Spark Driver Ausführungslogs;
- Per
/api/v1/...exportiertes JSON oder Event Log.
Das Ziel ist nicht, "ein paar Metriken anzusehen", sondern zu beantworten:
- Auf welcher Ebene ist diese Abfrage langsam: Scan, Shuffle, Join, Aggregation, Spill, GC, Scheduling, Kaltstart;
- Gibt es Datenneigung, und wenn ja, in welchem Stage / Task / SQL-Abschnitt;
- Welche Probleme sind datenbezogen und welche ressourcen- oder konfigurationsbezogen;
- Was ist der nächste Schritt: SQL ändern, Konfiguration anpassen oder Daten ergänzen.
Eingabepriorität
| Eingabe | Was kann getan werden |
|---|---|
| UI URL + Execution ID/Übermittlungszeit + SQL | Vollständigste, Task-Level-Diagnose |
| Ausführungslogs (mit App ID und UI URL) + SQL | Zuerst Logs parsen, dann auf UI zugreifen; falls UI nicht verfügbar, Rückfall auf Stage-Level |
| EXPLAIN FORMATTED | Nur Planstruktur- und SQL-Abschnittszuordnung |
| Event Log / History Server | Fallback, wenn UI abgelaufen ist |
Logs enthalten üblicherweise bereits:
application ID: application_xxx
application web UI: http://host:8088/proxy/application_xxx
Der Benutzer muss die UI URL also nicht separat erneut einfügen, aber die Erreichbarkeit der URL muss tatsächlich überprüft werden.
Arbeitsablauf
1. Eingaben sammeln und parsen
- App ID, UI URL, Operation ID, Stage/Job-Zeitlinie, Final Plan aus Logs extrahieren;
- Tabellennamen, Join-Bedingungen, group by / distinct / window / order by aus dem SQL-Originaltext extrahieren;
- Operatoren, Ein-/Ausgabespalten, Join-Bedingungen, Aggregationsschlüssel aus
EXPLAIN FORMATTEDextrahieren.
2. Tatsächliche Ausführung lokalisieren
- Bevorzugt Execution ID verwenden;
- Ansonsten nach SQL-Text + Übermittlungszeit in der
/sql-Liste matchen; /sqlgibt standardmäßig nur eine kleine Anzahl von Datensätzen ab offset=0 zurück; daher muss paginiert oder nach ID gesucht werden;- Bei mehreren Kandidaten den zeitlich nächsten und beschreibungsmäßig passendsten auswählen; falls immer noch nicht eindeutig, den Benutzer fragen.
3. Laufzeitdaten abrufen
Führen Sie das Skript aus (empfohlen). Das folgende scripts/ ist relativ zu diesem Skill-Verzeichnis; falls Sie in einem anderen Verzeichnis ausführen, wechseln Sie bitte zuerst in das Skill-Verzeichnis oder verwenden Sie absolute Pfade.
python scripts/spark_diagnose.py \
--url "http://host:8088/proxy/application_xxx" \
--exec-id 94 \
--sql-file query.sql \
--explain explain.txt \
--log run.log \
--out report.md \
--json report.json
Wenn die Execution ID unsicher ist:
python scripts/spark_diagnose.py \
--url "http://host:18080/history/application_xxx/" \
--sql-file query.sql \
--exec-time "2026-11-02T08:06:50Z" \
--out report.md
Authentifizierungsparameter:
--cookie "name=value; name2=value2"
--header "X-Token: ..."
--user "user:password"
--kerberos # Verwendet curl --negotiate
--insecure # Überspringt TLS-Überprüfung; nur für interne selbstsignierte Zertifikate
Nur-Lesen-Prinzip: Das Skript ruft nur GET auf, führt kein SQL aus und schreibt nicht in den Cluster.
4. Metriken interpretieren
Das Skript gibt strukturiertes JSON und Markdown aus. Besonders beachten:
- Stage-Zeitlinie: Wanduhrzeit vs.
executorRunTimevs. Task-Startverzögerung; - Task-Verteilung: max/median/p95 von Dauer, Datensätzen, Shuffle-Bytes;
- Echte Neigung: Datensätze und Dauer eines Tasks liegen gleichzeitig signifikant über dem Median;
- Falscher Longtail: Datensätze normal, aber
executorDeserializeTimehoch; meist kalte Executors; - Spill:
memoryBytesSpilled/diskBytesSpilled, sowiespill sizeim Plan-Knoten; - Plan-Knoten: Output rows / shuffle bytes / Dauer von Scan, Exchange, Join, Aggregate;
- Konfiguration: AQE, skewJoin-Schwellenwerte, Shuffle-Partitionsanzahl, Broadcast-Schwellenwert, dynamische Zuweisung.
5. Abschlussbericht schreiben
Das Skript liefert Beweise und Kandidatenschlussfolgerungen. Die endgültige Antwort muss die SQL-Semantik ergänzen:
- Operator-zu-SQL-Abschnitts-Zuordnung;
- Geschäftliche Bedeutung von Hot-Keys (falls aus SQL/Tabellenlogik ableitbar);
- Priorität und erwarteter Nutzen der Vorschläge;
- Klar kennzeichnen, welche Teile "externe Überprüfung benötigen".
Berichtsstruktur:
- Fazit zuerst (nach Auswirkungen sortiert);
- Ausführungsübersicht und Zeitlinie;
- Beweistabelle für Neigung/Longtail;
- SQL-Plan-Zuordnung;
- Konfiguration und Risiken;
- Vorschläge;
- Beweisquellen und Einschränkungen;
- Noch extern zu verifizierende Punkte.
Wichtige Entscheidungsregeln
Diese Regeln müssen befolgt werden, um die häufigsten Fehleinschätzungen zu vermeiden:
-
Neigung an Datensätzen und Dauer messen, nicht nur an Shuffle-Bytes. Ein stark komprimierbarer Hot-Key (z. B. viele
item_id=1) kann nur wenige MB belegen, aber 60 % der Datensätze ausmachen. -
Echte Neigung von Kaltstart unterscheiden. Ein langsamer Task mit normalen Datensätzen und hohem
executorDeserializeTime / Dauer-Verhältnis ist ein kalter Executor, keine Datenneigung. -
Partial Aggregation kann GROUP BY-Neigung verschleiern. Wenn der Plan
partial_count/partial_sumenthält, wird der Hot-Key vor dem Shuffle auf wenige Zeilen komprimiert; prüfen Sie, ob die Aggregationsschreibweise selbst die Neigung umgeht. -
count(DISTINCT)ist eine zweistufige Deduplizierung. Der erste Shuffle-Schlüssel enthält normalerweise das DISTINCT-Feld (z. B.(item_id, buyer_id)); Hotspots werden verteilt; nicht wie bei normalem GROUP BY beurteilen. -
AQE Skew Join ist größenbasiert. Die Bewertung basiert auf der komprimierten Partitionsgröße im Vergleich zu
skewedPartitionFactor/skewedPartitionThresholdInBytes; komprimierbare Hotspots können unter dem Schwellenwert liegen und werden nicht aufgeteilt. -
Mehr Shuffle-Partitionen verdünnt keinen einzelnen Hot-Key. Ein einzelner Key landet immer in einer Partition; je mehr Partitionen, desto kleiner die anderen, desto größer wird max/median.
-
Wenn die Wanduhrzeit des Stages viel größer als die Task-Laufzeit ist, zuerst Scheduling prüfen. Sehen Sie sich
launchTime - submissionTime, dynamische ZuweisungminExecutorsund YARN-Warteschlange an. -
Aufblähung nur dann vermuten, wenn die Anzahl der ausgegebenen Zeilen des Joins deutlich größer als die der eingehenden Zeilen ist. Wenn die Ausgabezeilen gleich der Anzahl der Fakttabellenzeilen sind, ist das Problem meist die Verteilung, nicht doppelte Schlüssel.
Grenzen
- Die tatsächlichen Dateninhalte sind nicht sichtbar; die konkreten Werte von Hot-Keys müssen vom Benutzer überprüft werden;
- Die genauen Ursachen von YARN-Warteschlangen und langsamer Containerzuweisung erfordern RM/Kyuubi-Logs;
- Probleme mit UDF/benutzerdefiniertem Code erfordern Code und Executor-Logs;
- Ohne UI/Event Log kann das reguläre Driver-Log nur eine Stage-Level-Diagnose durchführen;
- Es wird kein SQL ausgeführt, keine Daten geändert und kein Cookie/Token ausgegeben.
Referenzen
references/endpoints.md: REST-Endpunkte und Paginierung;references/metrics.md: Feldunterschiede und Einheitenumrechnung;references/heuristics.md: Schwellenwerte, Pläne und Neigungsbewertung.