REX | Spark - Shuffle
Contenu
Contenu
Certaines opérations dans Spark déclenchent un événement appelé shuffle.
Le shuffle est le mécanisme de Spark pour redistribuer les données afin qu’elles soient regroupées différemment entre les partitions.
Cela implique généralement la copie des données entre les exécuteurs et les machines, ce qui fait du shuffle une opération complexe et coûteuse.
Règle générale
On dit qu’un RDD qui lors de sa transformation dépend d’un autre de ses éléments ou de l’élément d’un autre RDD, celle-ci provoque du shuffle.
Il faut réduire autant que possible la communication réseau (qui provoque de la latence) et rallonge la durée de traitement d’un job Spark.
Les différents types de transformations
Narrow Dependencies
Ce type de transformation est rapide, car il ne nécessite pas de shuffle.
Chaque partition du RDD parent est utilisé au maximum d’une seule et unique partition du RDD enfant
- map, flatMap, mapValues, flatMapValues
- filter
- join (si le RDD parent est partitionné comme l’enfant)
- mapPartitions, mapPartitionsWithIndex
Wide Dependencies
Ce type de transformation passe par du shuffle de donnée sur le réseau.
Chaque partition du RDD parent peut être utilisée par une ou plusieurs partitions du RDD enfant
- cogroup, groupWith
- join (si le RDD parent n’est pas partitionné comme l’enfant)
- leftOuterJoin, rightOuterJoin, intersection
- groupByKey, reduceByKey, combineByKey
- distinct
- repartition, coalesce
Problématiques du distribué
Le paradigme du distribué introduit 2 problématiques par rapport aux systèmes classiques :
- Échec partiel: crash d’un sous-ensemble de machines impliquées dans un calcul distribué.
- Latence: certaines opérations ont une plus grande latence que d’autres à cause de la communication réseau.
Heureusement pour nous, Spark gère très bien ces deux problèmes.
En pratique
Il y a un impact dans la manière de programmer un job afin de réduire au maximum la latence.
Cas d’école: reduceByKey vs groupByKey
L’exemple du reduceByKey vs groupByKey est le plus connu.
Le groupByKey consiste à :
- effectuer le groupByKey sur le volume de donnée initial (gros shuffle)
- puis à réduire les éléments
Le reduceByKey consiste à :
- réduire les éléments une première fois dans chaque machine (mapper side first)
- effectuer le groupByKey sur un volume de donnée réduit (petit shuffle)
- réduire une deuxième fois après le shuffle
La communication réseau (latence), étant l’opération la plus longue et la plus coûteuse (network > disk > memory)
, le reduceByKey est l’opération qui transite le moins de données sur le réseau.
Règle générale
|
|
Debug
Pour vérifier le type de dépendance d’un RDD (narrow ou wide):
|
|
Pour afficher l’héritage du RDD (vérifier si un RDD a été conçu avec du shuffle ou non):
|
|
Conclusion
Le shuffle est un principe important à garder à l’esprit lorsque l’on développe sur un système distribué.