spark是基于MApreduce的一个并行计算框架。



Spark中数据的组织通过RDD方式完成。



RDD可以理解成为一组数据加上对数据的操作。



不可以更改的,但是RDD可以从一个RDD转换成为另外的一个RDD。




gender用什么类型spark_数据



窄依赖就类似于图上面的这种,一个前面的RDD中的partition只会被后面的一个RDD的partition所依赖。


gender用什么类型spark_gender用什么类型spark_02


宽依赖就类似于上面的这种,一个前面的partition会后面的至少两个partition所依赖。


那么划分宽窄依赖的好处是啥?(后面将会讲到)。


逻辑完全一致,不同的是作用于不同的数据集。


stage是任务是否向前推进的基本单位。


宽依赖是spark划分不同的stage的依据是通过宽依赖来进行划分的。


同一个stage中的task是可以并行执行的,看下图中的stage2,task1和task2之间,因为任务只依赖于前面的RDD中指定的partition,所以,task1和task2可以并行的执行。


时机是在任务执行前。


那么具体的划分stage的方法是什么呢?



大体的步骤是先生成该RDD的parent 的stage,然后生成该RDD的stage。例如:



这样好处就是,一个stage中的task是可以并行计算的,例如task1,task2,task3,都不需要外部干预就可以并行计算了。(这是我想的,具体实现是不是这样的还需要研究研究),但是Resulttask3、4、5的输入是来自于shuffle后的输出,从这点考虑,划分stage是便于管理咯?因为spark事先没有数据的元数据信息,所以其shuffle后才知道哪些数据应该生成哪些task上面扔。


gender用什么类型spark_并行计算_03



划分是从最后一个RDD,也就是G开始,可以看出,BG属于窄依赖,那么划分到一个stage中。GF是宽依赖,所以,划分到不同的stage中。


过来一条任务,spark会对它生成具体的DAG。生成的DAG中的最后一个RDD的划分任务的开始。



凡是和最后一个RDD是属于窄依赖的,被划分到和最后一个RDD的同一个stage中。


如果是宽依赖,那么就生成一个parent stage:


首先,这个正在划分stage的RDD会做判断:


---->parent stage 没有生成


    :生成新的stage


----->parent stage已经生成


元数据信息在RDD中,


如果某个partition的结果丢失了,也会记录这个丢失的结果。


这个结果会储存在Driver端,其他的task可以通过查询来使用task的结果。



当把stage划分好了以后,我们就要开始生成任务并执行了


任务的提交(或者就叫做的执行完毕后的提交)的规则是,一个stage的所以的parent stage都提交了后,这个stage中完成,这个stage才能够被提交。


所以,代码中是按照递归的方式来进行任务的推进的 ,如下:



SubmitStage(stage){  
  

   //这个我想的是,注册JobId用的 
 
  

       jobId = activeJobForStage( stage ) 
 
  

       missing = getMissingParentStage( stage ) // 获取到parent的中的哪些stage还没有完成的 
 
  

       if(mssing == Nil){ 
 
  

           //向TaskScheduler提交task/ResultTask,然后进行计算或者是读缓存 
  
  

           //先判断哪些partition是需哟啊计算的,那些需要计算的partition会生成一个task,然后提交给taskScheduler 
 
  

           submitMissgingTasks( stage , jobId);  
 
  

       }else { 
 
  

           for( parent <- missing){ // 如果还有parent的stage是没有运算好的,那么就递归的提交这些stage 
 
  
SubmitStage(stage)  
  

           } 
 
  

           watingSages += stage 
 
  

       } 
 
  

   }


未完待续..