Я думаю, что вопрос будет лучше сформулирован так:
Когда нам нужно вызвать кэш или сохранить на RDD?
Спарк процессы ленивы, то есть ничего не произойдет, пока не потребуется. Чтобы быстро ответить на вопрос, после val textFile = sc.textFile("/user/emp.txt")выдачи данных ничего не происходит, создается только a HadoopRDD, используя файл в качестве источника.
Допустим, мы немного изменим эти данные:
val wordsRDD = textFile.flatMap(line => line.split("\\W"))
Опять же, ничего не происходит с данными. Теперь есть новый RDD, wordsRDDкоторый содержит ссылку testFileи функцию, которая будет применяться при необходимости.
Только когда действие вызывается над RDD, например wordsRDD.countцепочкой RDD, называемой lineage, будет выполнено. То есть данные, разбитые по разделам, будут загружены исполнителями кластера Spark, flatMapбудет применена функция и будет вычислен результат.
На линейной линии, как та, что в этом примере, cache()не требуется. Данные будут загружены исполнителям, все преобразования будут применены и, наконец, countбудут вычислены все данные в памяти - если данные помещаются в память.
cacheполезно, когда линия RDD разветвляется. Допустим, вы хотите отфильтровать слова из предыдущего примера в счетчик положительных и отрицательных слов. Вы можете сделать это так:
val positiveWordsCount = wordsRDD.filter(word => isPositive(word)).count()
val negativeWordsCount = wordsRDD.filter(word => isNegative(word)).count()
Здесь каждая ветвь выдает перезагрузку данных. Добавление явного cacheоператора гарантирует, что обработка, выполненная ранее, будет сохранена и повторно использована. Работа будет выглядеть так:
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()
По этой причине cacheговорят, что он «нарушает родословную», поскольку создает контрольную точку, которую можно повторно использовать для дальнейшей обработки.
Основное правило: Используйте, cacheкогда линия вашего RDD разветвляется или когда RDD используется несколько раз, как в цикле.