转换基于现有RDD创建新RDD。基本上,RDD是不可变的,Spark中的所有转换都是惰性的。在执行操作但未处理数据之前,RDD中的数据不会被处理,新的RDD如何创建?例如,在filter
操作中,如何在不将RDD实际加载到内存并处理它的情况下创建新RDD?
答案 0 :(得分:4)
问题:例如,在过滤操作中,如何创建新的RDD 实际上将RDD加载到内存并进行处理?
例如:
firstRDD=spark.textFile("hdfs://...")
secondRDD=firstRDD.filter(someFunction);
thirdRDD = secondRDD.map(someFunction);
result = thirdRDD.count()
由于RDD是通过一组转换创建的,会记录这些转换,而不是实际数据(这就像行动计划,如果我们使用此特定过滤需要执行的操作计划预先生成)。生成一个RDD的这些转换的图形称为Lineage Graph,如下所示。
上面例子中的请参阅RDD.scala
只有在遇到使用filter
的谓词时,它才会创建新的RDD。
这就像行动计划。只有当您调用count
等行为时,才会执行此计划。
/*** Return a new RDD containing only the elements that satisfy a predicate.
*/
def filter(f: T => Boolean): RDD[T] = withScope {
val cleanF = sc.clean(f)
new MapPartitionsRDD[T, T](
this,
(context, pid, iter) => iter.filter(cleanF),
preservesPartitioning = true)
}
懒惰的评估:(纠正你的引用" Spark中的所有转换都是懒惰的 "到" 所有Spark中的转换被懒惰地评估 ")
Spark在第一次在动作中使用时懒得计算RDD, 这样它就可以进行管道转换。所以,在上面的示例RDD中 只有在调用
count()
操作时才会对其进行评估。
希望有帮助...
答案 1 :(得分:0)
Spark变换在运行中很懒惰。这些操作不会立即计算,它只记得在RDD上应用的转换并返回指向操作输出的指针。只有在对其应用操作时才会计算转换操作。应用操作后,spark会将操作分解为任务并将其分发到节点上以供执行。