Penso che la domanda sarebbe meglio formulata come:
Quando dobbiamo chiamare la cache o persistere su un RDD?
I processi Spark sono pigri, cioè non accadrà nulla finché non sarà necessario. Per rispondere rapidamente alla domanda, dopo che val textFile = sc.textFile("/user/emp.txt")
è stato emesso, non accade nulla ai dati, solo una HadoopRDD
viene costruita, usando il file come sorgente.
Diciamo che trasformiamo un po 'quei dati:
val wordsRDD = textFile.flatMap(line => line.split("\\W"))
Ancora una volta, non accade nulla ai dati. Ora c'è un nuovo RDD wordsRDD
che contiene un riferimento testFile
e una funzione da applicare quando necessario.
Solo quando viene chiamata un'azione su un RDD, come wordsRDD.count
la catena RDD, chiamata lignaggio, verrà eseguita. Cioè, i dati, suddivisi in partizioni, verranno caricati dagli esecutori del cluster Spark, la flatMap
funzione verrà applicata e il risultato verrà calcolato.
Su un lignaggio lineare, come quello in questo esempio, cache()
non è necessario. I dati verranno caricati sugli esecutori, verranno applicate tutte le trasformazioni e infine count
verranno calcolate, tutte in memoria - se i dati si adattano alla memoria.
cache
è utile quando il lignaggio del RDD si dirama. Supponiamo che tu voglia filtrare le parole dell'esempio precedente in un conteggio delle parole positive e negative. Potresti farlo in questo modo:
val positiveWordsCount = wordsRDD.filter(word => isPositive(word)).count()
val negativeWordsCount = wordsRDD.filter(word => isNegative(word)).count()
Qui, ogni ramo emette un ricaricamento dei dati. L'aggiunta di un'istruzione esplicita cache
assicurerà che l'elaborazione eseguita in precedenza venga conservata e riutilizzata. Il lavoro sarà simile al seguente:
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()
Per tale motivo, cache
si dice che "interrompa il lignaggio" in quanto crea un checkpoint che può essere riutilizzato per ulteriori elaborazioni.
Regola empirica: utilizzare cache
quando il lignaggio del proprio RDD si dirama o quando un RDD viene utilizzato più volte come in un ciclo.