在Apache Spark中,缓存RDD的目的是什么?

6

我是Apache Spark的新手,在阅读Spark材料时有几个基本问题无法理解。每种材料都有自己的解释风格。我正在使用PySpark Jupyter笔记本电脑在Ubuntu上进行实践。

据我所知,当我运行以下命令时,testfile.csv中的数据被分区并存储在相应节点的内存中(实际上我知道这是一种惰性评估,直到它看到动作命令才会处理),但概念仍然存在。

rdd1 = sc.textFile("testfile.csv")

我的问题是当我运行以下转换和操作命令时,rdd2数据将存储在哪里。
1. 它会存储在内存中吗?
rdd2 = rdd1.map( lambda x: x.split(",") )

rdd2.count()

我知道rdd2中的数据只有在关闭jupyter笔记本之前才可用。那么cache()有什么必要呢?无论如何,rdd2都可以进行所有转换。我听说,在所有转换完成后,内存中的数据会被清除,这是怎么回事?

  1. 将RDD保留在内存中和使用cache()有什么区别吗?

    rdd2.cache()


也许有点跑题,但我遇到了一个相关的问题:我的Pyspark决定在每次调用rdd或从该rdd构建的dfs时都在rdd内运行内置的udf。 rdd.cache()停止了这种行为。更重要的是,udf会在调用.cache()的点之后再次停止运行。因此,您越早检测到多次调用rdd或多次调用df,就越好。 - Lana Pro
1个回答

10

它会存储在内存中吗?

当您通过一个“操作”(如countprintforeach)运行Spark转换时,只有在这种情况下才会实现您的图形,并且在您的情况下文件被消耗。 RDD.cache 的目的是确保 sc.textFile("testfile.csv") 的结果可用于内存中,并且不需要再次读取。

不要将“变量”与实际在后台执行的操作混淆。缓存允许您重新迭代数据,确保如果有足够的内存将其全部存储在内存中,如果您想要重新迭代该RDD,并且设置了正确的“存储级别”(默认为StorageLevel.MEMORY)。来自文档(感谢@RockieYang):

此外,每个持久化的RDD都可以使用不同的存储级别进行存储。例如,您可以将数据集保存在磁盘上、将其作为序列化的Java对象存储在内存中(以节省空间)、在节点之间复制它或将其存储在Tachyon中。这些级别通过向persist()方法(Scala、Java、Python)传递StorageLevel对象来设置。cache()方法是使用默认存储级别的速记方式,即StorageLevel.MEMORY_ONLY(将反序列化对象存储在内存中)。您可以使用persist()或cache()方法将RDD标记为持久化。第一次在操作中计算时,它将保留在节点的内存中。Spark的缓存具有容错性 - 如果RDD的任何分区丢失,它将自动使用最初创建它的转换进行重新计算。

将RDD存储在内存中和使用cache()有什么区别吗?

如上所述,您可以通过cache将其保存在内存中,只要您提供了正确的存储级别。否则,在您想要重新使用它的时候,它不一定会保留在内存中。


我认为只有在存储级别为MEMORY_ONLY时才是真的。 - Rockie Yang
@RockieYang 你指的是什么?RDD将会被保存在内存中这个事实吗? - Yuval Itzchakov
我是指的是http://spark.apache.org/docs/latest/programming-guide.html#rdd-persistence。 - Rockie Yang
@RockieYang 创建拉取请求总是受欢迎的 :) - Yuval Itzchakov
@downvoter - 请随意告诉我这个答案有什么问题。 - Yuval Itzchakov
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接