12-twelve-ly/spark-sql-diagnosis

Analyse l'exécution des tâches Apache Spark / Spark SQL. À partir du SQL original, EXPLAIN FORMATTED, des logs d'exécution Kyuubi/Spark Driver et de l'URL Spark UI, identifie les goulets d'étranglement des requêtes lentes, l'asymétrie des données (data skew), le spill, le GC, les problèmes de planification/démarrage à froid, l'expansion des jointures et les problèmes de configuration.

Qu'est-ce que spark-sql-diagnosis ?

Cette compétence est conçue pour diagnostiquer en profondeur les tâches Apache Spark / Spark SQL en exploitant plusieurs sources de données : l'URL Spark UI (ou History Server / YARN proxy), le SQL original et son EXPLAIN FORMATTÉ, les logs Driver / Kyuubi, ou encore les fichiers event log. Elle va bien au-delà d'un simple affichage de métriques : elle répond à des questions précises comme "où se situe le goulot d'étranglement (scannage, shuffle, jointure, agrégation, spill, GC, planification, démarrage à froid) ?", "y a-t-il une asymétrie des données et sur quel stage / task / fragment SQL ?", "les problèmes sont-ils liés aux données, aux ressources ou à la configuration ?", et "quelle est la prochaine action recommandée : modifier le SQL, la configuration ou enrichir les données ?". Le workflow comprend la collecte et l'analyse des entrées, la localisation de l'exécution réelle via l'ID d'exécution ou la correspondance texte/temps, l'exécution d'un script Python (`scripts/spark_diagnose.py`) pour récupérer les données d'exécution (sans modifier le cluster, uniquement des GET), puis l'interprétation des indicateurs clés (time-line des stages, distribution des tâches, véritable skew vs faux tail, spill, nœuds du plan, configuration). Enfin, elle produit un rapport structuré combinant preuves, conclusions correctes et recommandations exploitables, en respectant des règles strictes pour éviter les erreurs fréquentes (confusion skew/démarrage à froid, agrégation partielle masquant le skew, etc.). Cette compétence est idéale pour les ingénieurs de données et les administrateurs Spark qui veulent identifier rapidement les causes racines des lenteurs, prioriser les actions et améliorer les performances des pipelines Spark. Elle est conçue pour fonctionner avec les plateformes utilisant Spark UI, Kyuubi, YARN, Spark History Server, et supporte l'authentification par cookie, header, ou Kerberos.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add 12-twelve-ly/spark-sql-diagnosis-skill

Installed? Explore more Recherche et analyse de données skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Diagnostic Spark SQL

Quand l'utiliser

À utiliser lorsque l'utilisateur fournit l'une des combinaisons suivantes :

  • Une URL Spark UI / History Server / YARN proxy ;
  • Une requête Spark SQL et son EXPLAIN FORMATTED ;
  • Les logs d'exécution Kyuubi / Spark Driver ;
  • Un JSON exporté via /api/v1/... , ou un event log.

L'objectif n'est pas de "regarder quelques métriques", mais de répondre à :

  1. À quel niveau cette requête est lente : scan, shuffle, jointure, agrégation, spill, GC, planification, démarrage à froid ;
  2. Y a-t-il une asymétrie des données (data skew), et sur quel stage / task / fragment SQL ;
  3. Les problèmes sont-ils liés aux données, aux ressources ou à la configuration ;
  4. La prochaine étape doit-elle être de modifier le SQL, la configuration, ou d'enrichir les données.

Priorité des entrées

EntréeCe qu'elle permet
URL UI + ID d'exécution / heure de soumission + SQLLa plus complète, diagnostic au niveau des tasks
Logs d'exécution (contenant app ID et URL UI) + SQLD'abord analyser les logs, puis accéder à l'UI ; si l'UI n'est pas disponible, dégradation au niveau des stages
EXPLAIN FORMATTEDUniquement analyse de la structure du plan et correspondance avec les fragments SQL
event log / History ServerSolution de repli après expiration de l'UI

Les logs contiennent généralement déjà :

application ID: application_xxx
application web UI: http://host:8088/proxy/application_xxx

L'utilisateur n'a donc pas besoin de coller à nouveau l'URL, mais il faut absolument vérifier si l'URL est accessible.

Workflow

1. Collecter et analyser les entrées

  • Extraire des logs : app ID, URL UI, operation ID, timeline des stages/jobs, Final Plan ;
  • Extraire du SQL original : noms de tables, conditions de jointure, group by / distinct / window / order by ;
  • Extraire de EXPLAIN FORMATTED : opérateurs, colonnes d'entrée/sortie, conditions de jointure, clés d'agrégation.

2. Localiser l'exécution réelle

  • Priorité à l'ID d'exécution ;
  • Sinon, faire correspondre le texte SQL + l'heure de soumission dans la liste /sql ;
  • /sql ne retourne par défaut qu'un petit nombre d'enregistrements à partir de offset=0 ; il faut paginer ou détecter par ID ;
  • En cas de plusieurs candidats, choisir celui dont la description correspond le mieux et dont la date est la plus récente ; si toujours pas unique, demander à l'utilisateur.

3. Récupérer les données d'exécution

Exécuter le script (recommandé). Le scripts/ ci-dessous est relatif au répertoire de cette compétence ; si vous exécutez depuis un autre répertoire, cd d'abord vers le répertoire de la compétence, ou utilisez un chemin absolu.

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

Si l'ID d'exécution est incertain :

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

Paramètres d'authentification :

--cookie "name=value; name2=value2"
--header "X-Token: ..."
--user "user:password"
--kerberos          # utilise curl --negotiate
--insecure          # ignore la validation TLS, réservé aux certificats auto-signés en interne

Principe de lecture seule : le script n'effectue que des appels GET, n'exécute pas de SQL, n'écrit pas sur le cluster.

4. Interpréter les indicateurs

Le script produit un JSON structuré et du Markdown. Concentrez-vous sur :

  • Timeline des stages : temps mural vs executorRunTime vs délai de démarrage des tâches ;
  • Distribution des tâches : max/médiane/p95 de duration, records, shuffle bytes ;
  • Vrai skew : le nombre d'enregistrements et la durée d'une tâche sont tous deux significativement supérieurs à la médiane ;
  • Faux tail : le nombre d'enregistrements est normal, mais executorDeserializeTime est élevé, généralement dû à un executor à froid ;
  • Spill : memoryBytesSpilled / diskBytesSpilled, ainsi que spill size des nœuds du plan ;
  • Nœuds du plan : Scan, Exchange, Join, Aggregate : output rows / shuffle bytes / duration ;
  • Configuration : AQE, seuil skewJoin, nombre de partitions shuffle, seuil de broadcast, allocation dynamique.

5. Rédiger le rapport final

Le script fournit les preuves et les conclusions candidates. La réponse finale doit impérativement être complétée en lien avec la sémantique SQL :

  • Correspondance opérateur → fragment SQL ;
  • Signification métier des clés chaudes (si elle peut être déduite du SQL / de la logique de création de table) ;
  • Priorité des recommandations et bénéfices attendus ;
  • Marquage explicite des parties nécessitant une validation externe.

Structure du rapport :

  1. Conclusion en premier (classée par impact) ;
  2. Aperçu de l'exécution et timeline ;
  3. Tableau des preuves de skew/long tail ;
  4. Correspondance du plan SQL ;
  5. Configuration et risques ;
  6. Recommandations ;
  7. Sources des preuves et limites ;
  8. Questions nécessitant encore une validation externe.

Règles clés de jugement

Ces règles doivent être respectées pour éviter les erreurs de diagnostic les plus courantes :

  1. Le skew se juge sur records et duration, pas uniquement sur shuffle bytes. Une clé chaude hautement compressible (par exemple beaucoup de item_id=1) peut ne représenter que quelques Mo, mais contenir 60% des enregistrements.

  2. Distinguer le vrai skew du démarrage à froid. Une tâche lente avec un nombre d'enregistrements normal et un rapport executorDeserializeTime / duration élevé est due à un executor à froid, pas à un skew.

  3. L'agrégation partielle peut masquer le skew GROUP BY. Lorsque le plan contient partial_count / partial_sum, les clés chaudes sont compressées en quelques lignes avant le shuffle ; il faut vérifier si la syntaxe d'agrégation elle-même contourne le skew.

  4. count(DISTINCT) est une déduplication en deux phases. La clé du premier shuffle contient généralement le champ distinct (par exemple (item_id, buyer_id)), les points chauds sont dispersés ; ne pas juger comme un GROUP BY ordinaire.

  5. Le skew join AQE est basé sur la taille. Le critère est la taille de la partition après compression par rapport à skewedPartitionFactor / skewedPartitionThresholdInBytes ; une clé chaude compressible peut être inférieure au seuil et ne pas être fractionnée.

  6. Augmenter le nombre de partitions shuffle ne dilue pas une clé chaude unique. Une clé unique va toujours dans une seule partition ; plus il y a de partitions, plus les autres sont petites, ce qui augmente le rapport max/médiane.

  7. Quand le temps mural d'un stage est très supérieur au temps d'exécution des tâches, vérifier d'abord la planification. Regarder launchTime - submissionTime, minExecutors de l'allocation dynamique, la file YARN.

  8. Ne suspecter une expansion de jointure que si le nombre de lignes en sortie est nettement supérieur au nombre de lignes en entrée. Si le nombre de lignes en sortie est égal au nombre de lignes de la table de faits, le problème est généralement la distribution, pas des clés en double.

Limites

  • Le contenu réel des données n'est pas visible ; les valeurs spécifiques des clés chaudes nécessitent que l'utilisateur consulte les données ;
  • Les files d'attente YARN et les causes lentes d'allocation de conteneurs nécessitent les logs RM/Kyuubi ;
  • Les problèmes de code UDF/personnalisé nécessitent le code et les logs des executors ;
  • Sans UI/event log, les logs Driver ordinaires ne permettent qu'un diagnostic au niveau des stages ;
  • N'exécute pas de SQL, ne modifie pas les données, n'affiche pas les cookies/tokens.

Références

  • references/endpoints.md : Points de terminaison REST et pagination ;
  • references/metrics.md : Différences de champs et conversion d'unités ;
  • references/heuristics.md : Seuils, plan et jugement des skew.

Skills associés