(为什么)我们需要在RDD上调用缓存或持久化

(为什么)我们需要在RDD上调用缓存或持久化

当从文本文件或集合(或从另一个RDD)创建弹性分布式数据集(RDD)时,我们是否需要显式调用“cache”或“persist”来将RDD数据存储到内存中?或者默认情况下RDD数据是以分布式方式存储在内存中的吗?

val textFile = sc.textFile("/user/emp.txt")

根据我的理解,在上面的步骤之后,textFile是一个RDD,并且可以在节点的所有/部分内存中使用。

如果是这样,为什么我们需要在textFile RDD上调用“cache”或“persist”呢?


蝴蝶不菲
浏览 783回答 3
3回答

慕尼黑8549860

大多数RDD操作都是懒惰的。将RDD视为一系列操作的描述。RDD不是数据。所以这一行:val textFile = sc.textFile("/user/emp.txt")它什么都不做。它创建了一个RDD,上面写着“我们需要加载这个文件”。此时未加载该文件。需要观察数据内容的RDD操作不能是懒惰的。(这些被称为动作。)一个例子是RDD.count- 告诉你文件中的行数,需要读取文件。因此,如果您编写textFile.count,此时将读取文件,将对行进行计数,并返回计数。如果再打电话textFile.count怎么办?同样的事情:文件将被读取并再次计数。什么都没有存储。RDD不是数据。那怎么RDD.cache办?如果您添加textFile.cache到上面的代码:val textFile = sc.textFile("/user/emp.txt")textFile.cache它什么都不做。RDD.cache也是一个懒惰的操作。该文件仍未读取。但是现在RDD说“读取这个文件,然后缓存内容”。如果您textFile.count第一次运行,则将加载,缓存和计算该文件。如果textFile.count再次呼叫,操作将使用缓存。它只会从缓存中获取数据并计算行数。缓存行为取决于可用内存。例如,如果文件不适合内存,textFile.count则会回退到通常的行为并重新读取文件。

小唯快跑啊

我们是否需要显式调用“cache”或“persist”来将RDD数据存储到内存中?是的,仅在需要时。RDD数据默认以分布式方式存储在内存中?没有!这些是为什么:Spark支持两种类型的共享变量:广播变量,可用于缓存所有节点的内存中的值;累加器,它们是仅“添加”到的变量,例如计数器和总和。RDD支持两种类型的操作:转换(从现有数据集创建新数据集)和操作(在数据集上运行计算后将值返回到驱动程序)。例如,map是一个转换,它通过一个函数传递每个数据集元素,并返回一个表示结果的新RDD。另一方面,reduce是一个使用某个函数聚合RDD的所有元素的操作,并将最终结果返回给驱动程序(尽管还有一个返回分布式数据集的并行reduceByKey)。Spark中的所有转换都是惰性的,因为它们不会立即计算结果。相反,他们只记得应用于某些基础数据集的转换(例如文件)。仅当操作需要将结果返回到驱动程序时才会计算转换。这种设计使Spark能够更有效地运行 - 例如,我们可以意识到通过map创建的数据集将用于reduce,并仅将reduce的结果返回给驱动程序,而不是更大的映射数据集。默认情况下,每次对其执行操作时,都可以重新计算每个转换后的RDD。但是,您也可以使用持久化(或缓存)方法在内存中保留RDD,在这种情况下,Spark会在群集上保留元素,以便在下次查询时更快地访问。还支持在磁盘上保留RDD或在多个节点上复制。有关更多详细信息,请查看Spark编程指南。
打开App,查看更多内容
随时随地看视频慕课网APP