懒惰背景下的转型与行动
Posted
技术标签:
【中文标题】懒惰背景下的转型与行动【英文标题】:Transformation vs Action in the context of Laziness 【发布时间】:2018-04-10 12:09:39 【问题描述】:正如“学习火花:闪电般快速的大数据分析”一书中所述:
由于 Spark 计算 RDD 的方式不同,转换和操作也有所不同。
在对惰性进行了一些解释后,我发现,转换和动作都是惰性的。因此,问题是,引用的句子是什么意思?
【问题讨论】:
谁否决了这个问题?这似乎是一个完全有效的问题。 Foreach 是一个动作。如果您的最终操作要从自定义函数内部执行某些操作,它为您提供了一种触发执行的方法。例如,您可以使用 foreach 中的自定义函数调用而不是 RDD/DF 写入方法之一来保存到自己的数据库。 是什么让您认为转换和操作都是懒惰的? 【参考方案1】:对比 RDD 动作和转换的惰性并不一定有效。
正确的说法是,从 RDD 作为数据集合的角度来看,RDD 是惰性求值的:创建 RDD 实例时,内存中不一定有“数据”。
该语句提出的问题是:RDD 的数据何时加载到内存中?可以改写为“RDD 何时被评估?”。在这里,我们区分了动作和转换:
考虑以下代码序列:
第 1 行:
rdd = sc.textFile("text-file-path")
RDD 存在吗? 是的。 数据是否加载到内存中? 否。 --> RDD 评估是惰性的
第 2 行:
rdd2 = rdd.map(lambda line: list.split())
RDD 存在吗? 是的。实际上,有 2 个 RDD。 数据是否加载到内存中? 否。 --> 尽管如此,它还是很懒惰,Spark 所做的只是记录如何加载和转换数据,记住沿袭(如何从另一个派生 RDD)。
第 3 行
print(rdd2.collect())
RDD 存在吗? 是(仍然有 2 个 RDD)。 数据是否加载到内存中? 是的。
有什么区别? collect()
强制 Spark 返回转换结果。 Spark 现在完成了它在步骤 #1、#2 和 #3 中记录的所有内容。
在 spark 的术语中,#1 和 #2 是转换。
转换通常会返回另一个 RDD
实例,这是识别 lazy 部分的提示。
#3 有一个操作,它简单地表示一个操作,该操作导致计划在转换中被执行,以便返回结果或执行最终操作,例如保存结果(是的,“比如保存实际加载到内存中的数据集合”)。
所以,简而言之,我会说 RDD 是惰性求值的,但在我看来,将操作(动作或转换)标记为惰性与否是不正确的。
【讨论】:
【参考方案2】:转换是惰性的,动作不是。
定义:
Transformation - 将集群上的数据变异出来的函数。这些操作将在执行时更改数据。这方面的示例是映射、过滤器和聚合。这些在调用动作之前不会执行。
Action - 导致数据被持久化或返回到驱动程序的任何函数(还有 foreach,它并不真正属于这两个类别)。
为了运行一个动作(比如保存数据),到目前为止您请求的所有转换都必须运行以实现数据。如果 Spark 查看您要运行的操作的总体执行计划,则可以实现优化,因此在需要之前不要计算任何内容是有益的。
【讨论】:
以上是关于懒惰背景下的转型与行动的主要内容,如果未能解决你的问题,请参考以下文章