Кэшируется ли Spark RDD на рабочем узле или узле драйвера (или обоих)?

Может кто-нибудь, пожалуйста, исправьте мое понимание о сохранении Искры.

Если мы выполнили кеш() на RDD, его значение кэшируется только на тех узлах, где на самом деле вычислялось RDD. Значение: если существует кластер из 100 узлов, а RDD вычисляется в разделах первого и второго узлов. Если мы будем кэшировать этот RDD, то Spark будет кэшировать его значение только в первом или втором рабочих узлах. Поэтому, когда это приложение Spark пытается использовать этот RDD на более поздних этапах, тогда драйвер Spark должен получить значение от первых/вторых узлов.

Правильно ли я?

(ИЛИ)

Это то, что значение RDD сохраняется в памяти драйвера, а не на узлах?

Ответ 1

Изменить это:

тогда Spark собирается кэшировать свое значение только в первом или втором рабочих узлах.

на это:

тогда Spark собирается кэшировать свое значение только в первом и втором рабочих узлах.

и... Да, правильно!

Spark старается свести к минимуму использование памяти (и нам это нравится!), Поэтому он не будет загружать ненужную память, поскольку он вычисляет каждое утверждение лениво, то есть не выполняет никакой реальной работы при любом преобразовании он будет ожидать выполнения действия, которое не оставляет Spark никакого выбора, кроме как выполнять фактическую работу (читать файл, передавать данные в сеть, выполнять вычисления, собирать результат обратно в драйвер, например..).

Видите ли, мы не хотим кэшировать все, если только мы не можем это сделать (то есть, объем памяти позволяет это делать (да, мы можем запросить больше памяти у исполнителей или/и драйвера, но иногда наш кластер просто не имеет ресурсов, что обычно встречается, когда мы обрабатываем большие данные), и это действительно имеет смысл, то есть то, что кэшированный RDD будет использоваться снова и снова (поэтому его кэширование ускорит выполнение нашей работы).

Вот почему вы хотите unpersist() свой RDD, когда он вам больше не нужен...! :)

Проверьте это изображение с одной из моих работ, где я запросил 100 исполнителей, однако на вкладке "Исполнители" отображено 101, т.е. 100 рабов/рабочих и один мастер/драйвер:

enter image description here

Ответ 2

RDD.cache - это ленивая операция. он ничего не делает, пока вы не вызовете действие, подобное счету. Как только вы вызываете действие, операция будет использовать кеш. Он просто возьмет данные из кеша и выполнит операцию.

RDD.cache- Сохраняет RDD с уровнем хранения по умолчанию (только для памяти).             Spark RDD API

2.Is что-то, что значение RDD сохраняется в памяти драйвера, а не на узлах?

RDD может сохраняться на диске и в памяти. Нажмите ссылку на документ Spark для всех параметров Spark Rdd Persist

Ответ 3

# no actual caching at the end of this statement
rdd1=sc.read('myfile.json').rdd.map(lambda row: myfunc(row)).cache()

# again, no actual caching yet, because Spark is lazy, and won't evaluate anything unless
# a reduction op
rdd2=rdd2.map(mysecondfunc)

# caching is done on this reduce operation. Result of rdd1 will be cached in the memory of each worker node
n=rdd1.count()

Итак, чтобы ответить на ваш вопрос

Если мы выполнили cache() для RDD, его значение кэшируется только на тех узлах, где RDD был вычислен изначально

Единственная возможность кэширования чего-либо находится на рабочих узлах, а не на узлах драйверов.

Функция cache может применяться только к RDD (см.), а поскольку RDD существует только в памяти рабочего узла (устойчивые распределенные наборы данных!), Это приводит к кэшируются в памяти соответствующего рабочего узла. Как только вы применяете операцию, подобную count, которая возвращает результат драйверу, он больше не является RDD, он просто является результатом вычисления, выполненного RDD рабочими узлами в их соответствующей памяти

Поскольку cache в вышеприведенном примере вызывался на rdd2, который все еще находится на нескольких рабочих узлах, кэширование происходит только в памяти рабочего узла.

В приведенном выше примере, когда снова выполнить какую-то карту-красную операцию на rdd1, он больше не будет читать JSON, потому что он был кэширован

К вашему сведению, я использую слово memory, исходя из предположения, что уровень кэширования установлен на MEMORY_ONLY. Конечно, если этот уровень изменяется на другие, Spark будет кэшировать либо в memory, либо storage в зависимости от настроек

Ответ 4

Вот отличный ответ на кеширование

(Почему) нам нужно вызвать кеш или сохранить его на RDD

В основном кэширование хранит RDD в памяти/диске (на основе набора уровней устойчивости) этого node, так что когда этот RDD вызывается снова, ему не нужно перекомпилировать его линию (lineage - набор предварительных преобразований выполненный, чтобы находиться в текущем состоянии).