Apache火花在RDD上应用地图转换

时间:2015-03-06 08:19:51

标签: apache-spark bigdata rdd

我有一个HadoopRDD,我从中创建了第一个带有简单Map功能的RDD,然后用第一个RDD创建了第二个RDD,带有另一个简单的Map功能。类似的东西:

HadoopRDD - > RDD1 - > RDD2。

我的问题是Spak是否会通过记录迭代HadoopRDD记录以生成RDD1然后它将按记录迭代RDD1记录以生成RDD2,或者它是否通过HadoopRDD进行整合然后一次生成RDD1然后生成RDD2。

2 个答案:

答案 0 :(得分:3)

简答:rdd.map(f).map(g)将一次性执行。

TL;博士

Spark将作业分成几个阶段。应用于数据分区的阶段是任务。

在一个阶段,Spark将尝试管理尽可能多的操作。 “可能”取决于重新排列数据的需要:需要改组的操作通常会打破管道并创建一个新阶段。

实际上:

Given `rdd.map(...).map(..).filter(...).sort(...).map(...)`

将导致两个阶段:

.map(...).map(..).filter(...)
.sort(...).map(...)

可以使用rdd.toDebugString从rdd检索 上面的相同工作示例将产生此输出:

val mapped = rdd.map(identity).map(identity).filter(_>0).sortBy(x=>x).map(identity)

scala> mapped.toDebugString
res0: String = 
(6) MappedRDD[9] at map at <console>:14 []
 |  MappedRDD[8] at sortBy at <console>:14 []
 |  ShuffledRDD[7] at sortBy at <console>:14 []
 +-(8) MappedRDD[4] at sortBy at <console>:14 []
    |  FilteredRDD[3] at filter at <console>:14 []
    |  MappedRDD[2] at map at <console>:14 []
    |  MappedRDD[1] at map at <console>:14 []
    |  ParallelCollectionRDD[0] at parallelize at <console>:12 []

现在,谈谈你的问题的关键点:流水线非常有效。完整的管道将应用于每个分区的每个元素一次。这意味着rdd.map(f).map(g)的执行速度与rdd.map(f andThen g)一样快(有一些可忽略的开销)

答案 1 :(得分:0)

Apache Spark将按照没有特定顺序的记录迭代HadoopRDD记录(数据将被拆分并发送给工作人员)并且&#34;应用&#34;计算RDD1的第一个转换。之后,第二次转换应用于RDD1的每个元素以获得RDD2,再次没有特定的顺序,依此类推以进行连续的转换。您可以从map方法签名中注意到它:

// Return a new RDD by applying a function to all elements of this RDD.
def map[U](f: (T) ⇒ U)(implicit arg0: ClassTag[U]): RDD[U]

Apache Spark遵循DAG(定向非循环图)执行引擎。在需要值之前,它实际上不会触发任何计算,因此您必须区分transformationsactions

编辑:

就性能而言,我并不完全了解Spark的底层实现,但我知道除了在相关阶段添加额外(不必要的)任务之外,不应该有重大的性能损失。根据我的经验,你通常不会使用相同&#34;自然的变换&#34;连续(在这种情况下连续两次map)。在进行洗牌操作时,您应该更关注性能,因为您正在移动数据,这会对您的工作绩效产生明显影响。 Here您可以找到与此相关的常见问题。