Spark WordCount运行原理
一个spark任务可以有多个stage,一个stage可以有多个Task,真正执行任务的就是Task对象
在一个stage中一个分区就是一个Task
RDD的依赖关系
1、Lieage:血统、遗传
- RDD最重要的特性之一,保存了RDD的依赖关系
- RDD实现了基于Lineage的容错机制
2、依赖关系:
- 宽依赖:一个父RDD的分区被子RDD的多个分区使用,例如map、flatMap、filter、union等操作都会产生窄依赖;(独生子女)
- 窄依赖:一个父RDD的分区被子RDD的一个分区使用,例如distinct、groupByKey、reduceByKey、sortByKey、join等操作都会产生宽依赖;(超生)
3、宽依赖对比窄依赖
- a)宽依赖对应shuffle操作,需要再运行时将同一个父RDD的分区传入到不同的子RDD分区中,不同的分区可能位于不同的节点,就可能涉及多个节点间数据传输
- b)当RDD分区丢失时,Spark会对数据进行重新计算,对于窄依赖只需重新计算一次子RDD的父RDD分区
注:相比于宽依赖,窄依赖对优化更有利
DAG工作原理
根据RDD之间的依赖关系,形成一个DAG(有向无环图)
DAGScheduler将DAG划分为多个Stage
- a)划分依据:是否发生宽依赖(Shuffle)
- b)划分规则:从后往前,遇到宽依赖切割为新的Stag
- c)每个Stage由一组并行的Task组成
为什么需要划分Stage
- 1、数据本地化
移动计算,而不是移动数据
保证一个Stage内不会发生数据移动 - 2、最佳实践
尽量避免Shuffle
提前部分聚合减少数据移动
因此spark划分stage的整体思路是:
从后往前推,遇到宽依赖就断开,划分为一个stage;遇到窄依赖就将这个RDD加入该stage中。因此在图2中RDD C,RDD D,RDD E,RDDF被构建在一个stage中,RDD A被构建在一个单独的Stage中,而RDD B和RDD G又被构建在同一个stage中。
Spark Shuffle过程
在分区之间重新分配数据
- 父RDD中同一分区中的数据按照算子要求重新进入子RDD的不同分区中
- 中间结果写入磁盘
- 由子RDD拉取数据,而不是由父RDD推送
- 默认情况下,Shuffle不会改变分区数量