Я думаю, что вопрос будет лучше сформулирован так:
Когда нам нужно вызвать кэш или сохранить на 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 используется несколько раз, как в цикле.