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 wordsRDD
que contém uma referência testFile
e uma função a serem aplicadas quando necessário.
Somente quando uma ação é chamada em um RDD, como wordsRDD.count
a cadeia RDD, chamada linhagem , será executada. Ou seja, os dados, divididos em partições, serão carregados pelos executores do cluster Spark, a flatMap
funçã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 cache
declaraçã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 cache
quando a linhagem do seu RDD se ramifica ou quando um RDD é usado várias vezes como em um loop.