Aller au contenu

Partie 2 – Spark Core : RDD, PairRDD et exécution

  • 10h45 – 12h00
  • Apports : 25 min
  • TP 2 : 30 min
  • Partage + quiz express : 20 min

Et si on ouvrait le capot ? Au TP 1, votre count() a produit 1 job et N tâches. Pourquoi N ?

Le RDD (Resilient Distributed Dataset) est la structure de base de Spark. Un fichier trips.csv lu par Spark devient un RDD découpé en partitions, et chaque partition est confiée à un Executor sur une machine du cluster.

RDD = trips.csv
┌────────────┬────────────┬────────────┬────────────┐
│ Partition 1│ Partition 2│ Partition 3│ Partition 4│
└─────┬──────┴─────┬──────┴─────┬──────┴─────┬──────┘
└── Machine A – Executor ──┘ └── Machine B – Executor ──┘
LettreSignificationConséquence
ResilientSi une partition est perdue (machine en panne), Spark la reconstruit grâce à sa lignée – la « recette » des transformations qui l’ont produitePas de copie des données, juste la recette
DistributedChaque partition est traitée par un Executor, en parallèle1 partition = 1 tâche
DatasetCollection immuable : transformer un RDD, c’est en créer un nouveauPas de modification en place

Analogie de la lignée : si on perd une page du livre, on refait la recette plutôt que de stocker une photocopie de chaque page.

Un PairRDD est un RDD de couples (clé, valeur). C’est lui qui permet reduceByKey, join, sortByKey, countByKey. L’exemple ci-dessous est exactement le TP 2 : clé = zone de départ, valeur = montant.

(132, 45.2) (132, 12.0) (48, 30.1) (48, 9.5)
│ reduceByKey(lambda a, b: a + b)
▼
(132, 57.2) (48, 39.6) = chiffre d'affaires par zone

reduceByKey pré-agrège sur chaque partition avant d’échanger les données entre machines ; groupByKey envoie toutes les valeurs sur le réseau. Le bonus du TP 2 le mesure : ≈ 480 Ko de Shuffle Write pour groupByKey contre ≈ 7 Ko pour reduceByKey, soit environ 70 fois moins de données échangées.

Transformations, actions et évaluation paresseuse

Section intitulée « Transformations, actions et évaluation paresseuse »
lignes = sc.textFile("data/trips.csv") # transformation
donnees = lignes.filter(lambda l: not l.startswith("VendorID")) # transformation
champs = donnees.map(lambda l: l.split(",")) # transformation
longs = champs.filter(lambda c: float(c[4]) > 10) # trajets > 10 miles
longs.count() # ACTION : le calcul démarre ici

Les quatre premières lignes répondent instantanément : rien n’est calculé. Spark construit un plan, le DAG. C’est l’action (count, collect, take, saveAsTextFile…) qui déclenche l’exécution. C’est l’évaluation paresseuse : elle permet à Spark d’optimiser l’ensemble du plan avant de lancer quoi que ce soit.

Transformations (paresseuses)Actions (déclenchent un job)
map, filter, flatMap, distinctcount, collect, first, take(n)
reduceByKey, groupByKey, join, sortBytakeOrdered(n), reduce, saveAsTextFile
TypeExemplesCe qui se passeCoût
Narrowmap, filterChaque partition de sortie dépend d’une seule partition d’entrée : traitement sur place, sans réseauFaible
WidereduceByKey, join, groupByKey, sortByChaque partition de sortie reçoit des morceaux de toutes les partitions d’entrée (par clé) : les données changent de machine = shuffleÉlevé : réseau et disque

Message clé : 1 shuffle = 1 nouveau stage. C’est le premier levier de performance d’un job Spark.

SparkContext (Spark 1.x)SparkSession (depuis Spark 2.0)
Point d’entrée historique de Spark CorePoint d’entrée unique : SQL, DataFrames, streaming
Crée les RDD : sc.textFile, sc.parallelizeContient le SparkContext : spark.sparkContext
Un seul par applicationRemplace SQLContext et HiveContext
Complété à l’époque par SQLContext et HiveContextSeul point d’entrée en Spark Connect (pas de RDD côté client)

On crée toujours une SparkSession ; sc = spark.sparkContext si on a besoin des RDD. Avec Spark Connect (client léger qui parle à un serveur Spark distant), l’API RDD n’existe pas côté client : une raison de plus de préférer les DataFrames (partie 4).

RDD Objects DAG Scheduler Task Scheduler Worker
votre code ──▶ découpe le DAG en ──▶ envoie les tâches ──▶ les Executors
construit le DAG stages aux shuffles via le cluster manager exécutent les tâches
  • DAG (Directed Acyclic Graph) : le plan d’exécution, sans boucle.
  • 1 action = 1 job → plusieurs stages (un par shuffle, plus un) → 1 tâche par partition.
  • Les tâches d’un même stage tournent en parallèle.

Dans la Spark UI du TP 2 (onglet Jobs › DAG Visualization), vous verrez exactement ceci : un stage 1 avec textFile, filter, map, puis une flèche (le shuffle de reduceByKey), puis un stage 2 avec l’agrégation et takeOrdered. Compter les tâches du premier stage = compter les partitions : c’est la réponse à l’accroche de la partie.

→ TP 2 – Top 10 des zones avec les RDD (30 min)

Puis le quiz express : transformation ou action ? Combien de stages ?

  • Pourquoi reduceByKey est-il plus rapide que groupByKey ? Il pré-agrège dans chaque partition avant le shuffle : environ 70 fois moins de données échangées (mesuré : ≈ 7 Ko contre ≈ 480 Ko).
  • Combien de stages avez-vous vus, et pourquoi ? Deux : la lecture + map, puis l’agrégation après le shuffle. Le join et le sortBy de l’étape 5 en ajoutent d’autres.
  • À retenir : 1 shuffle = 1 nouveau stage. C’est là que se joue la performance.

Transition : « Les données sont encore sur un seul disque. Et si elles ne tenaient plus ? » → Partie 3 – Hadoop, HDFS et Spark sur un cluster

Dépôt des participants : formations2026/formation-spark-ml (branche participants)

Contenu pédagogique © Ambient IT · 140 Avenue Jean Lolive, 93500 Pantin · formation@ambient-it.net · +33 (0)1 48 10 09 46

Organisme de formation enregistré sous le numéro 11 75 54743 75. Cet enregistrement ne vaut pas agrément de l'État.