为什么Spark只会惰性计算RDD?

为什么Spark只会惰性计算RDD?为什么只有第一次在一个行动操作中用到时,才会真正计算?

这个问题本质上讲很复杂,这是spark设计上必须要这么做,不然spark就无法干掉mapreduce。
1. 首先我们需要理解这惰性计算
spark将对RDD的操作分为transformation和action,action一共只有五个操作:save、count、collect、lookup、reduce。当然像distinct这种操作我们认为它是复合操作,中间过程包括reduce。
只有当action执行,才会整理计算逻辑,创建job,并生成DAG,然后在DAG根据shuffle操作(宽依赖、窄依赖)更细粒度的拆分stage,启动相应数量的task计算中间结果,stage by stage的计算,就这样支撑了整个spark计算的框架。
2. 这种惰性计算是最优做法
所谓的惰性计算,其实只是表象,本质上都是并行计算(流水线计算),比如map1 -> filter -> map2 -> collect。a1做完map1,进入filter,此时a2进入map1...其实并不是惰性计算。
3. 如果讲到spark设计,本质上这种设计很棒,没什么问题。同时也在考虑一个问题内存管理以及高可用。对于mapreduce来讲,在计算层面不会考虑容灾问题,因为底层hdfs的多副本会保证数据安全,但是spark就没那么幸运了,再设计时不会落盘(尽量不要),那怎么解决容灾问题?RDD采用的是dependency解决,在这种情况下拆分成stage就很好,因为这种粒度大一些,一旦数据丢失只会重启stage。如果不是惰性计算,那就倒霉了,每一个操作都将是一个RDD,对于spark来讲这种粒度太细了,管理起来不容易

  • ## # uyy6fy****
  1. *

Spark的惰性计算恰巧就是它优于MR的成功之处,所谓的惰性计算并不会像之前的MR那样进行相应的储存浪费很多空间和时间,毕竟我们不是马上要通过Spark筛选出很多数据。
而Spark的转换操作其实就是只计算求结果时真正的数据。
在行动操作First()中,Spark只需要扫描文件知道找到第一个匹配的行为位置,并不需要读取整个文件,这一点就成为了Saprk优于MR的关键所在。