Spark RDD 是否缓存在工作节点或驱动程序节点(或两者)上?

Is Spark RDD cached on worker node or driver node (or both)?

谁能纠正我对 Spark 坚持的理解。

如果我们在 RDD 上执行了 cache() ,它的值只会缓存在最初实际计算 RDD 的那些节点上。 意思是,如果有一个 100 个节点的集群,并且 RDD 在第一个和第二个节点的分区中计算。如果我们缓存这个 RDD,那么 Spark 将只在第一个或第二个工作节点中缓存它的值。 因此,当这个 Spark 应用程序在后期尝试使用这个 RDD 时,Spark 驱动程序必须从 first/second 个节点获取值。

我说的对吗?

(或)

RDD 值是否保存在驱动程序内存中而不是节点上?

这里有一个关于缓存的优秀答案

(Why) do we need to call cache or persist on a RDD

基本上缓存将 RDD 存储在该节点的内存/磁盘(基于持久性级别集)中,因此当再次调用此 RDD 时,它不需要重新计算其沿袭(沿袭 - 先前转换的集合执行到当前状态)。

RDD.cache 是懒操作。它什么都不做,除非你调用像计数这样的动作。调用操作后,操作将使用缓存。它只会从缓存中获取数据并执行操作。

RDD.cache- 持久化具有默认存储级别的 RDD(仅内存)。 Spark RDD API

2.Is RDD 值保存在驱动程序内存中而不是节点上?

RDD 也可以持久化到磁盘和内存中。单击 link to Spark 文档以获取所有选项 Spark Rdd Persist

改变这个:

then Spark is going to cache its value only in first or second worker nodes.

对此:

then Spark is going to cache its value only in first and second worker nodes.

和...正确!

Spark 尝试最小化内存使用(我们喜欢它!),因此它不会产生任何不必要的内存负载,因为它 lazily 评估每个语句,也就是说,它不会对任何 转换 做任何实际工作,它会等待 动作 发生,这让 Spark 别无选择,比做实际工作(读取文件,将数据传送到网络,进行计算,将结果收集回驱动程序,例如..)。

你看,我们不想缓存所有内容,除非我们真的可以(即内存容量允许)(是的,我们可以在执行程序中请求更多内存 or/and驱动程序,但有时我们的集群只是没有资源,这在我们处理 大数据 时很常见)而且它确实有意义,即缓存的 RDD 将被再次使用并且再次(所以缓存它会加速我们工作的执行)。

这就是为什么您想要 unpersist() 您的 RDD,当您不再需要它时......! :)

查看这张图片,来自我的一个工作,我在那里请求了 100 个执行程序,但是执行程序选项卡显示 101,即 100 slaves/workers 和一个 master/driver:

# 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()

所以回答你的问题

If we have performed a cache() on an RDD its value is cached only on those nodes where actually RDD was computed initially

缓存某些内容的唯一可能性是在工作节点上,而不是在驱动程序节点上。

cache 函数只能应用于 RDD (refer),并且由于 RDD 仅存在于工作节点的内存中(弹性 Distributed Datasets!),它的结果缓存在各自的工作节点内存中。一旦你应用像 count 这样的操作将结果返回给驱动程序,它就不再是真正的 RDD 了,它只是工作节点在各自内存中完成 RDD 计算的结果

由于上例中的 cache 是在仍然位于多个工作节点上的 rdd2 上调用的,因此缓存仅发生在工作节点的内存中。

在上面的例子中,当再次对 rdd1 执行一些 map-red 操作时,它不会再次读取 JSON,因为它被缓存了

仅供参考,我使用 memory 这个词是基于缓存级别设置为 MEMORY_ONLY 的假设。当然,如果该级别更改为其他级别,Spark 将根据设置

缓存到 memorystorage