【发布时间】:2015-04-15 10:56:46
【问题描述】:
谁能解释一下,RDD 转换的结果是什么?是新的数据集(数据副本)还是只是新的指针集,指向过滤的旧数据块?
【问题讨论】:
标签: apache-spark rdd
谁能解释一下,RDD 转换的结果是什么?是新的数据集(数据副本)还是只是新的指针集,指向过滤的旧数据块?
【问题讨论】:
标签: apache-spark rdd
RDD 转换允许您在 RDD 之间创建依赖关系。依赖关系只是产生结果的步骤(程序)。血统链(依赖字符串)中的每个 RDD 都有一个计算其数据的函数,并有一个指向其父 RDD 的指针(依赖关系)。 Spark 会将 RDD 依赖项划分为阶段和任务,并将它们发送给工作人员执行。
如果你这样做:
val lines = sc.textFile("...")
val words = lines.flatMap(line => line.split(" "))
val localwords = words.collect()
words 将是一个包含对行 RDD 的引用的 RDD。程序执行时,首先执行行函数(从文本文件加载数据),然后对结果数据执行单词函数(将行拆分为单词)。 Spark 是惰性的,因此除非您调用一些会触发作业创建和执行的转换或操作(在此示例中为收集),否则不会执行任何操作。
因此,RDD(也是转换后的 RDD)不是“一组数据”,而是程序中的一个步骤(可能是唯一的步骤)告诉 Spark 如何获取数据以及如何处理数据。
【讨论】:
转换基于现有 RDD 创建新的 RDD。基本上,RDD 是不可变的。 Spark 中的所有转换都是惰性的。在执行操作之前,不会处理 RDD 中的数据。
RDD 转换示例: 地图,过滤器,flatMap,groupByKey,reduceByKey
【讨论】:
正如其他人所提到的,RDD 维护着一个列表,其中列出了以编程方式应用于它的所有转换。这些是惰性求值的,所以尽管(例如在 REPL 中),您可能会得到不同参数类型的结果(例如,在应用映射之后),“新”RDD 还不包含任何内容,因为没有什么可以迫使原始 RDD 评估其沿袭中的转换/过滤器。 count等方法,各种归约方法等都会导致运输被应用。 checkpoint 方法也应用所有 RDD 操作,返回一个 RDD,它是传输的结果,但没有沿袭(这可能是性能优势,尤其是迭代应用程序)。
【讨论】:
所有答案都是完全有效的。我只想添加一张快速图片:-)
【讨论】:
转换是一种将 RDD 数据从一种形式转换为另一种形式的操作。当你在任何 RDD 上应用这个操作时,你会得到一个新的 RDD 转换后的数据(Spark 中的 RDD 是不可变的,还记得吗????)。 map、filter、flatMap 等操作都是转换。
现在有一点需要注意,那就是当你在任何 RDD 上应用转换时,它不会立即执行操作。它将使用应用的操作、源 RDD 和用于转换的函数创建一个 DAG(有向无环图)。它将继续使用引用构建此图表,直到您对最后排列的 RDD 应用任何操作操作。这就是为什么 Spark 中的转换是惰性的。
【讨论】:
其他答案已经给出了很好的解释。这是我的一些美分:
要知道返回的RDD里面有什么,最好检查一下RDD抽象类里面有什么(引用源代码):
在内部,每个 RDD 都有五个主要属性:
- 分区列表
- 计算每个分割的函数
- 对其他 RDD 的依赖列表
- (可选)键值 RDD 的分区器(例如说 RDD 是哈希分区的)
- (可选)计算每个拆分的首选位置列表(例如 HDFS 文件的块位置)
【讨论】: