Spark-Streaming架构详解

spark_submit==>SparkSubmin==>main===>sumit()==>doRunMain()===>runMain()==>通过反射的反射注册我们自定义的类,得到一个mainClass
==>mainClass.getMethod("main",new Array[String](0).getClass)获得到我们编写任务的主类的main方法
==》mainMethod.invoke(null,childArgs.toArray)开始执行我们主类的main方法,也就是开始执行我们秩序员自己编写的代码
==》创建sparkConf对象==》创建sparkContext对象==》创建SparkStreaming对象==》创建输入的dstream===》对输入的dstream进行不断的转换操作
==》调用output算子触发任务===》调用ssc.start方法启动整个Application任务===》ssc.awaitTermination()方法将任务阻塞,一直让其运行


具体流程(图解流程)
1.我们编写的sparStreaming程序大成jar包 然后调用spark-submit脚本,提交任务
2.通过反射的方式创建我们编写的主类的实例对象 然后调用main方法运行我们自己编写的代码
3.开始创建StreamingContext对象
4.在进行ssc初始化的时候会创建一个特别重要的对象JobScheduler,同时JobScheduler在做初始化的时候也会创建一个很重要的对象 JobGenerator
JobScheduler作用:将JobGenerator生成的任务job,进行任务分配给指worker上的executor执行
JobGenerator作用:根据DstreamGraph定义的算子和各个Dstream之间的依赖关系,去生成一个job,然后将这个job提交给jobScheduler做任务的提交,这个任务是对每个batch interval生成的rdd做计算
5.当对ssc初始化完了之后,就开始创建输入的Dstream,然后对dstream定义transform操作,最后调用output算子(这里只是定义,并没有真正执行)
6.当定义dstream计算逻辑结束后,开始调用StreamingCountext.start()方法启动整个应用程序,在启动时,会创建一个特别重要的对象DstreamGraph
DstreamGraph作用:保存了我们创建的输入的Dstream转换操作关系
7.在调用ssc.start()方法时,启动了DstreamGraph后,会立即调用之前创建的JobScheduler.start()方法,在这个方法中会创建一个重量级对象ReceiverTracker
8.开始调用ReceiverTracker的start()方法,在这个start方法中,首先会获取DstreamGraph中保存的dstream的所有receivers,然后将Receiver封装成startAllReceivers发送给ReceiverTrackerEndpoint对象,在这个方法中定义了启动receiver的核心逻辑,最后调用SparkContext的submitJob方法将需要启动的receiver以任务的形式发送到executor执行启动receiver
9.发送任务给executor启动receiver
10.将receiver封装成ReceiverSupervisorImpl 然后调用器start方法
11.这里启动了一个BlockGenerstor,运行在worker的executor中,负责数据的接收
12.调用具体的receiver的onStart方法,在onStart方法里面又调用了具体的输入流dsream的receive()方法接收数据
receiver作用:接收输入数据源数据
13.将接收的数据保存在BlockGenerstor 持久化currentBuffer缓存区中
currentBuffer作用:保存了receiver发送过来的原始数据
14.每个200毫秒 blockIntervalTimer会将数据打包成block
   blockIntervalTimer作用:每个batch interval时间将currentBuffer缓存中的数据全部打包封装成一个block   时间间隔是200ms
   blocksForPushing作用 : 是一个队列,保存了定时器推送过来的block,这个队列默认大小是10
15.将打包好的block推送给blocksForPushing
16.blockPushingThread后台线程启动后,就会调用keepPushingBlocks方法,在这个方法中,就会每隔一段时间,就回去blocksForPushing队列中回去block
17.从blocksForPushing拉取出来了队首的block,如果拿到了block就调用pushBlock进行推送,最终通过ReceiverSupervisorImpl的pushAndReportBlock方法,在这个方法中通过
  调用receivedBlockHandler.storeBlock()方法将block存储到blockManager中,同时将数据封装成ReceivedBlockInfo发送到ReceiverTracker中去
18.保存数据到blockManager中
19.将blockInfo发送到ReceiverTracker中去      发送-----
20.定时调度generateJobs方法,在这个方法中调用allocateBlocksToBatch方法,将当前时间段内的block分配给一个batch,然后调用DStreamGraph的generateJobs()方法,来根    据我们定义的DStream之间的依赖关系和算子,生成job。如果成功创建了job从ReceiverTracker中,获取到当前batch interval对应的block数据,用JobScheduler提交job。
   其对应的原始数据,就是那一批block

你可能感兴趣的:(Spark,Spark-Streaming,Spark)