一个Application对应至少1个Job。一个Job对应至少1个Stage。一个Stage对应至少1个Task。
其中:
- Task的数量与RDD的分区数量相当。分区数量取决于数据量和Executor的数量 * Executor的核数。
- 当有1个Action算子被触发时,会提交1个Job。
如果1个Stage中的RDD经过多次转换,分区数量从5变为4再变为3,则最终Task的数量等于最后一个RDD分区的数量。
一个worker是网络中的一个节点,一个Executor是一个进程(JVM),Task运行在线程维度。
1个action算子执行前可能经历若干transformation算子。可以组合为pipeline的算子(窄依赖)会合并为1个stage。例如:filter().map().count()是1个stage。
filter().mapToPair().reduceByKey().collect()会拆分为2个stage,因为reduceByKey()是宽依赖。
为什么以shuffle依赖作为stage切分的标准
stage的划分是贪婪的,尽可能多的包含算子,但是当出现宽依赖,比如reduceByKey依赖上一个mapToPair全部执行完成之后,才可以执行,否则数据就会不算,因此最多截止到reduceByKey能合并成一个大stage。只有等这一个大stage完成后,才可以进行下一个stage的执行。
宽依赖 vs 窄依赖
窄依赖:父分区只会把数据给到一个子分区。
宽依赖:父分区的数据会给到多个子分区。
join为什么有时候是宽依赖,有时候是窄依赖
当且仅当2个rdd的分区规则完全一样时,窄依赖,其他时候均为宽依赖。
当rdd1有2个分区,key是奇数一个分区,偶数一个分区,rdd2也有2个分区,key是奇数一个分区,偶数一个分区。join时候,不会shuffle。
网友评论