一、内核架构剖析

  • Spark学习之路(二):Spark核心术语详讲及作业提交流程一文中,已经详细介绍了Spark的核心术语,并且结合术语来简单粗略介绍了Spark作业的提交流程,这对于入门Spark而言已经足够,但是仅仅只是了解作业的提交流程而没有理解整体的底层架构是不够的,只有理解了内核架构,才能在作业出错时定位错误点,且可以针对性地调优,同时也是为精通Spark打好理论基础。下面基于Spark的作业提交流程来剖析内核架构。
  • 手绘一张Spark内核架构的简略图,以下会结合这张图片详细介绍:
    Spark学习之路(十 一):精通Spark核心编程之内核架构剖析-LMLPHP
    1.当我们写好一个Spark作业并打包好时,就要将程序提交到集群中去运行,使用shell命令spark-submit提交,而执行这条命令提交代码的机器,统称是提交Spark代码的机器。
    2.提交的Spark程序会在某台机器(取决于提交的模式,以后会详细介绍,在这里先略过,不影响架构介绍),就图中而言就是提交代码的机器,启动Driver程序,Driver程序可以认为就是我们写的Spark业务代码,此时回想一下,我们在编写Spark业务代码的第一步是做什么?毫无疑问,就是创建SparkContext实例,所以代码被提交后首先运行Driver程序,然后初始化SparkContext。
    3.SparkContext的初始化工作最重要的两件事情就是,初始化DAGScheduler和TaskScheduler,这两个调度器直接关系到Spark作业的划分与调度,很重要。
    4.初始化后的TaskScheduler实例会向Spark集群中的Master申请注册Application,Master在收到TaskScheduler的请求后,会挑选一个Worker节点,在该节点上启动Executor,并在Eexcutor上启动Application。
    5.Application会与Master进行通讯,根据配置向Master申请Executor。
    6.Application会在Master选定的Worker上启动用于执行Spark作业的Executor,Executor会初始化一个线程池ThreadPool,每当有Task被调度这里被执行时都会先把Task使用TaskRunner包装,TaskRunner主要负责反序列化传送过来的Task等一些Task的初始化工作,然后Executor会从TgreadPool中取出一个线程去执行该TaskRunner。
    7.被Application启动用于执行Task的Executor会向TaskScheduler反向注册,TaskScheduler会把这些反向注册的Executor的主机地址等信息封装好,放进Executor的队列中,成为以后调度Task的资源队列。
    8.TaskScheduler会根据Task的调度算法,从队列中取出Executor来调度Task。
  • 综上,经过理解了Spark的内核架构之后,对于Spark的作业提交流程可以深入了解它的提交流程了:Spark作业被打包并通过spark-submit命令被提交,然后在某一台机器上,会执行该作业的driver程序,driver首先将SparkContext初始化,SparkContext初始化时会初始化DAGScheduler和TaskScheduler,TaskSchduler实例初始化结束后会向集群的Master申请Executor来启动Application,Application启动后会向Master注册并申请用于执行作业的Executor,Executor被启动的同时会初始化一个ThreadPool,这是因为Task是以线程的方式在Executor上执行的,所以一个Executor可以并发执行Task,初始化结束后的Executor会向TaskScheduler注册,进入TaskScheduler的资源队列,到这一步时,所有的初始化工作完成。
  • 初始化工作完成后,Driver会继续执行,遇到action算子时会触发一个job,将其提交给DAGScheduler,DAGScheduler会根据stage划分算法将job划分为若干个stage,为每个stage根据配置创建一个Taskset,并将Taskset提交给TaskScheduler,TaskScheduler会根据Task调度算法,从Executor资源队列中取出Executor来执行Task(实际上是将该Task的相关序列化后提交到合适Executor的Worker上去执行)。
  • Executor收到发送过来的Task信息,将其使用TaskRunner进行封装,反序列化Task的信息,然后从ThreadPool取出一个线程来执行该TaskRunner。

二、总结

  • 结合图片,相信可以大致理解Spark的内核架构,相比于之前只是简单了解Spark的作业提交及运行,在剖析完内核架构后,对于Spark的作业提交及运行的理解肯定又会深一步,为以后精通Spark打下坚实的基础!感谢你的阅读,如有错误请不吝赐教。
  • 更多内容可以查看 萧邦主的技术博客导航
08-24 14:54