Je pense que la question serait mieux formulée comme suit:
Quand devons-nous appeler le cache ou persister sur un RDD?
Les processus Spark sont paresseux, c'est-à-dire que rien ne se passera tant que ce n'est pas nécessaire. Pour répondre rapidement à la question, après l' val textFile = sc.textFile("/user/emp.txt")émission, rien n'arrive aux données, seul un HadoopRDDest construit, en utilisant le fichier comme source.
Disons que nous transformons un peu ces données:
val wordsRDD = textFile.flatMap(line => line.split("\\W"))
Encore une fois, rien n'arrive aux données. Il existe maintenant un nouveau RDD wordsRDDqui contient une référence testFileet une fonction à appliquer en cas de besoin.
Ce n'est que lorsqu'une action est appelée sur un RDD, comme wordsRDD.countla chaîne RDD, appelée lignage, sera exécutée. Autrement dit, les données, réparties en partitions, seront chargées par les exécuteurs du cluster Spark, la flatMapfonction sera appliquée et le résultat sera calculé.
Sur une lignée linéaire, comme celle de cet exemple, cache()n'est pas nécessaire. Les données seront chargées dans les exécuteurs, toutes les transformations seront appliquées et finalement countelles seront calculées, le tout en mémoire - si les données tiennent en mémoire.
cacheest utile lorsque la lignée du RDD se ramifie. Supposons que vous souhaitiez filtrer les mots de l'exemple précédent en un décompte de mots positifs et négatifs. Vous pouvez faire ceci comme ça:
val positiveWordsCount = wordsRDD.filter(word => isPositive(word)).count()
val negativeWordsCount = wordsRDD.filter(word => isNegative(word)).count()
Ici, chaque branche émet un rechargement des données. L'ajout d'une cachedéclaration explicite garantira que le traitement effectué précédemment est conservé et réutilisé. Le travail ressemblera à ceci:
val textFile = sc.textFile("/user/emp.txt")
val wordsRDD = textFile.flatMap(line => line.split("\\W"))
wordsRDD.cache()
val positiveWordsCount = wordsRDD.filter(word => isPositive(word)).count()
val negativeWordsCount = wordsRDD.filter(word => isNegative(word)).count()
Pour cette raison, cacheon dit de «briser la lignée» car il crée un point de contrôle qui peut être réutilisé pour un traitement ultérieur.
Règle de base: à utiliser cachelorsque la lignée de votre RDD se ramifie ou lorsqu'un RDD est utilisé plusieurs fois comme dans une boucle.