Eu acho que a pergunta seria melhor formulada como:
Quando precisamos chamar o cache ou persistir em um RDD?
Os processos de faísca são preguiçosos, ou seja, nada acontecerá até que seja necessário. Para responder rapidamente à pergunta, após a val textFile = sc.textFile("/user/emp.txt")emissão, nada acontece com os dados, apenas a HadoopRDDé construído, usando o arquivo como fonte.
Digamos que transformamos esses dados um pouco:
val wordsRDD = textFile.flatMap(line => line.split("\\W"))
Novamente, nada acontece com os dados. Agora, há um novo RDD wordsRDDque contém uma referência testFilee uma função a serem aplicadas quando necessário.
Somente quando uma ação é chamada em um RDD, como wordsRDD.counta cadeia RDD, chamada linhagem , será executada. Ou seja, os dados, divididos em partições, serão carregados pelos executores do cluster Spark, a flatMapfunção será aplicada e o resultado será calculado.
Em uma linhagem linear, como a deste exemplo, cache()não é necessário. Os dados serão carregados para os executores, todas as transformações serão aplicadas e, finalmente count, serão computadas, todas na memória - se os dados couberem na memória.
cacheé útil quando a linhagem do RDD se ramifica. Digamos que você queira filtrar as palavras do exemplo anterior em uma contagem de palavras positivas e negativas. Você poderia fazer isso assim:
val positiveWordsCount = wordsRDD.filter(word => isPositive(word)).count()
val negativeWordsCount = wordsRDD.filter(word => isNegative(word)).count()
Aqui, cada ramificação emite uma recarga dos dados. A adição de uma cachedeclaração explícita garantirá que o processamento feito anteriormente seja preservado e reutilizado. O trabalho terá a seguinte aparência:
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()
Por esse motivo, cacheé dito que 'quebra a linhagem', pois cria um ponto de verificação que pode ser reutilizado para processamento adicional.
Regra geral: use cachequando a linhagem do seu RDD se ramifica ou quando um RDD é usado várias vezes como em um loop.