Ich denke, die Frage wäre besser formuliert als:
Wann müssen wir den Cache aufrufen oder auf einer RDD bestehen bleiben?
Spark-Prozesse sind faul, das heißt, nichts wird passieren, bis es erforderlich ist. Um die Frage schnell zu beantworten val textFile = sc.textFile("/user/emp.txt"), passiert nach der Ausgabe nichts mit den Daten, sondern nur eine HadoopRDD, die die Datei als Quelle verwendet.
Nehmen wir an, wir transformieren diese Daten ein wenig:
val wordsRDD = textFile.flatMap(line => line.split("\\W"))
Auch hier passiert nichts mit den Daten. Jetzt gibt es eine neue RDD wordsRDD, die einen Verweis auf testFileund eine Funktion enthält, die bei Bedarf angewendet werden kann.
Nur wenn eine Aktion für eine RDD aufgerufen wird, wie z. B. wordsRDD.countdie RDD-Kette, die als Linie bezeichnet wird, wird sie ausgeführt. Das heißt, die in Partitionen aufgeschlüsselten Daten werden von den Ausführenden des Spark-Clusters geladen, die flatMapFunktion wird angewendet und das Ergebnis wird berechnet.
Auf einer linearen Linie wie der in diesem Beispiel cache()wird nicht benötigt. Die Daten werden in die Ausführenden geladen, alle Transformationen werden angewendet und schließlich countwerden die Transformationen berechnet, alle im Speicher - wenn die Daten in den Speicher passen.
cacheist nützlich, wenn sich die Abstammungslinie des RDD verzweigt. Angenommen, Sie möchten die Wörter des vorherigen Beispiels in eine Anzahl für positive und negative Wörter filtern. Sie könnten dies so tun:
val positiveWordsCount = wordsRDD.filter(word => isPositive(word)).count()
val negativeWordsCount = wordsRDD.filter(word => isNegative(word)).count()
Hier gibt jeder Zweig ein erneutes Laden der Daten aus. Durch Hinzufügen einer expliziten cacheAnweisung wird sichergestellt, dass die zuvor durchgeführte Verarbeitung beibehalten und wiederverwendet wird. Der Job wird so aussehen:
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()
Aus diesem Grund cachewird gesagt, "die Linie zu brechen", da es einen Prüfpunkt schafft, der für die weitere Verarbeitung wiederverwendet werden kann.
Faustregel: Verwenden cacheSie diese Option , wenn sich die Abstammungslinie Ihres RDD verzweigt oder wenn ein RDD wie in einer Schleife mehrmals verwendet wird.