spark运行过程解析

1、懒执行

数据从源头到处理,并不是每一步操作都会立刻执行。在spark操作方法中,分为Transformation与Action两类操作。

    transformation:一个方法由RDD调用,执行后产生另一个RDD。

    Action:一个方法由RDD调用,执行后不是产生另一个RDD,而是产生一个非RDD的结果,例如collect,count。

Transformation方法会懒执行,而Action方法会立即执行,并且会将之前未执行的Transformation一并执行。

2、spark中的shuffle

shuffle本质是将数据汇总后重新分发的过程。这个过程如果数据量很大,会写入磁盘,降低程序性能。所以spark不能完全避免shuffle,只能尽量减少。

shuffle过程spark早期设计会产生大量的小文件同时读写,磁盘同时处理多个文件,降低了spark性能。在1.5.0版本后,spark修改为只生成一个大文件,并对数据进行排序,附加索引信息。这样减少了文件数量,并通过排序索引的方式提升了性能。但排序索引也会消耗时间,所有的设计都有取舍。

3、DAG( Directed Acyclic Graph))有向无环图

    Spark所有连续的transformation都不立即执行,而是根据执行计划组件一个执行的有向无环图,称之为DAG。直到遇到一个Action类型操作,整个DAG才真正开始执行。这样的目的在于,DAG有向无环图执行过程中可以优化减少shuffle的过程,提高执行效率(注意:hadoop就是因为每次shuffle必须要落入磁盘,才导致运行缓慢)

4、RDD依赖

    RDD之间的依赖:整个DAG为一个RDD转换为另一个RDD的过程。此过程中父RDD与子RDD的关系称之为子RDD对父RDD的依赖,通过子RDD保存父RDD的学员关系来实现。

    RDD依赖,分为宽依赖与窄依赖。

    窄依赖:父RDD中的所有分区都只面向一个字RDD的分区

    宽依赖:父RDD有分区面向多个子RDD中的分区

    窄依赖可以省略shuffle过程,以此来提高执行效率。(注意:当RDD为宽依赖或者RDD大于内存,需要shuffle落地磁盘)

     整个DAG中有多个连续的窄依赖,spark将这些连续窄依赖连续执行,中间不执行shuffle从而提高效率,这样的优化方式称之为流水线优化。

5、spark处理RDD的过程

    spark遇到Transformation类型操作时懒执行,直到遇到Action操作,则将此时之前的Transformation类型和操作和当前Action类型操作组成一个有向无环图DAG。从Action方法向前回溯,如果遇到的是Transformation则流水线优化,继续向前找,直到遇到宽依赖,无法实现优化,则将这一段执行过程组装成一个stage。再从当前宽依赖继续向前找,重复刚才的步骤,从而将DAG划分为若干stage。

    最终,一个DAG对应一个spark的Job,而其中划分出来的stage就是Job当中的task。RDD中可能有多个分区,这个task可能有多个实例来分布式并发处理数据。这样减少了task的数量,减少了shuffle的过程,减少了数据落地的情况和由于shuffle的全局栅栏造成对性能的影响,使得spark比hadoop性能更好。

6、spark可靠性保证

在RDD中保存了血缘关系,这样当子RDD在处理中出现问题,可以回溯到最初的数据(最近的stage的头部),整个stage重新计算,这样就保证了计算的可靠性。

但是每次都从头计算,效率低,如果提前设计RDD缓存,则可以找到缓冲数据,继续使用。这是一个效率优化点。

猜你喜欢

转载自blog.csdn.net/starkpan/article/details/86652078