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 testFile
und eine Funktion enthält, die bei Bedarf angewendet werden kann.
Nur wenn eine Aktion für eine RDD aufgerufen wird, wie z. B. wordsRDD.count
die 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 flatMap
Funktion 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 count
werden die Transformationen berechnet, alle im Speicher - wenn die Daten in den Speicher passen.
cache
ist 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 cache
Anweisung 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 cache
wird gesagt, "die Linie zu brechen", da es einen Prüfpunkt schafft, der für die weitere Verarbeitung wiederverwendet werden kann.
Faustregel: Verwenden cache
Sie diese Option , wenn sich die Abstammungslinie Ihres RDD verzweigt oder wenn ein RDD wie in einer Schleife mehrmals verwendet wird.