RDD 一旦创建好了,可以提供两种不同类型的操作:变换(transformation)和动作
(action)。变换是从前一个 RDD 构造出一个新的 RDD。例如,有一个常见的变换
是用谓词匹配来过滤数据。在我们之前的文本文件的示例中,我们可以用这个变
换来创建一个新的 RDD,这个 RDD 容纳的数据是只包含了单词“Python”的字
符串。如示例 3-2 所示:
示例
3-2
:调用
filter()
变换
>>> pythonlines = lines.filter(lamda line: “Python” in line)
动作,另一方面来看,是基于 RDD 来计算某个结果,并将结果返回给驱动程序
或者保存结果到一个外部的存储系统(比如 HDFS)。更早之前我们调用过一个
动作的例子是 first()。它返回 RDD 中的第一个元素,示例 3-3 展示了这点:
示例
3-3
:调用
first()
动作
>>> pythonlines.first()
u'## Interactive Python Shell'
变换和动作不相同是因为 Spark 计算 RDD 的方式。虽然,在任何时候你都可以
定义一个新的 RDD,但是 Spark 总是以一种 lazy 的方式计算它们,也就是它们
被第一次用于动作的时候。这种方式最初可能觉得不太寻常,但是当你开始处理
大数据时,你就会有同感了。举例来说,考虑下前面的示例 3-2 和示例 3-3,我
们定义了一个文本文件 RDD 然后过滤出了包含“Python”的行。如果当我们一
写完 lines = sc.textFile(...)语句,Spark 就立刻加载和保存整个文件的所有行的话,
考虑到我们马上就要过虑掉很多的行,这会导致浪费很多存储空间。反过来说,
一旦 Spark 知道了整个变换链,它就能只计算结果需要的数据。实际上,对于 first()
动作来说,Spark 只需要扫描文件直到它找到第一个符合条件的行就可以了,这
甚至不需要读整个文件。
最后,每次你执行个动作,Spark 的 RDD 默认会被重新计算。如果你想在多个
动作中重用 RDD,你可以用 RDD.persist()要求 Spark 对 RDD 持久化。我们可以
用一些不同的方式要求 Spark 对我们的数据持久化,详见表 3-6。在初次计算之
评论