热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Spark源码(7)SparkContext初始化源码分析

一、SparkContext初始化上次阅读到Master通知Worker启动了一个Driver,就是启动了一个JVM,并且开始使用反射的方式执行Dri

一、SparkContext 初始化

上次阅读到 Master 通知 Worker 启动了一个 Driver,就是启动了一个 JVM,并且开始使用反射的方式执行 DriverWrapper 的 main 方法。

假设我们提交了一个 JavaWordCount 程序到集群上,其实接下来就开始执行这个方法:

然后开始创建 SparkContext

SparkSession spark = SparkSession.builder().appName("JavaWordCount").getOrCreate();

点进去,可以看到:

SparkContext.getOrCreate(sparkConf)

这里 new 了一个 SparkContext(),然后开始看 SparkContext 的构造方法,这个方法尤其的长,但我们得抓住重点。

重点就在 500 多行的这里,创建了 SchedulerBackend,TaskScheduler,DAGScheduler

下面简单的介绍下这三个核心组件的作用:

(1)TaskScheduler

TaskScheduler 是一个 trait,它的核心任务是提交 TaskSet 到集群并汇报结果,并且向 DAGScheduler 汇报任务的执行情况。

主要实现类是 TaskSchedulerImpl

(2)SchedulerBackend

SchedulerBackend 也是一个 trait,不同的部署模式有不同的实现,比如在 standalone 模式下,实现类是:StandaloneSchedulerBackend。

它内部有两个 Endpoint 组件,一个是 DriverEndpoint ,用来和 Worker 打交道,比如创建 Executor、提交 Task 等;一个是 ClientEndpoint 用来和 master 打交道。

SchedulerBackend 专门负责收集 Worker 上的资源信息,它知道每个任务在提交时,自己拥有多少资源,然后去具体运行 Task。

(3)DAGScheduler

DAGScheduler 的主要作用是:当执行 action 算子的时候,DAGScheduler 会从最后一个 rdd 开始往前递归寻找 ShuffleDependency,每找到一个就会划分一个 stage,最终达到的目的是,根据业务逻辑算子依赖关系,划分成一个个 stage,并且根据 stage 先后关系,把 stage 转化成 ShuffleMapTask 或者 ResultTask,封装成 TaskSet,交给 TaskScheduler 提交。

最后要注意的是,DAGScheduler 和 SchedulerBackend 都是 TaskSchedulerImpl 的成员变量。


二、TaskScheduler 的创建

下面回到创建 TaskScheduler 的地方:

val (sched, ts) = SparkContext.createTaskScheduler(this, master, deployMode)

这个方法中,主要是根据不同的部署模式,分别创建不同的 TaskScheduler 和 SchedulerBackend。

在 Standalone 模式下:

创建了 TaskSchedulerImpl 对象和 StandaloneSchedulerBackend 对象。

在 TaskSchedulerImpl 的构造方法中,看到了两个重要的属性,dagScheduler 和 backend,其他倒没有什么逻辑了。

然后看到 StandaloneSchedulerBackend 的构造方法

这里要注意一下继承关系,继承了 CoarseGrainedSchedulerBackend

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GwvcTFpp-1637895026068)(C:/Users/wangkai/AppData/Roaming/Typora/typora-user-images/image-20210927222927252.png)]

然后父类里有一个很重要的属性,在执行构造的方法的时候,就会执行这个

image-20210927223019809

也就是说,在这句代码执行的时候:

val backend = new StandaloneSchedulerBackend(scheduler, sc, masterUrls)

其实,就创建了一个 DriverEndpoint 组件了,那么紧接着就需要看一下 DriverEndpoint 类的 onStart() 方法:

每间隔一段时间,就给自己发送了一个 ReviveOffers 消息

image-20210927223246758

这个消息的处理逻辑就很长了,需要单独一次来阅读了。可以一句话总结它干的事情:过滤出所有的资源,找到所有需要启动的 TaskSet,分配资源,启动任务。

然后再回来看 StandaloneSchedulerBackend 的构造方法,构造方法里没有逻辑,接着回到 SparkContext 往下看。

接下来,scheduler 调用了 initialize 方法:

scheduler.initialize(backend)

这个方法就把当前的 SchedulerBackend 绑定到自己的成员属性上:

接着 new 了 DAGScheduler

_dagScheduler = new DAGScheduler(this)

然后启动 TaskScheduler()

_taskScheduler.start()

三、TaskScheduler 的启动

首先看到实现类 TaskSchedulerImpl 类的 start() 方法

调动了内部的 SchedulerBackend 的启动方法:

这个方法中,首先封装了一个 CoarseGrainedExecutorBackend 类的启动命令

把这个 Command 封装到 ApplicationDescription,应用程序的描述信息中

然后把 ApplicationDescription 作为成员变量,并且还创建了一个 StandaloneAppClient 对象

image-20210927224615633

然后给启动了起来,new 了一个 ClientEndpoint() ,注意这是一个 Endpoint

image-20210927224712411

看一下它的 onStart() 方法,向 Master 注册

最终是给 Master 发送了一个 RegisterApplication 消息,消息里有 ApplicationDescription(应用程序的描述信息)


四、总结

这一切都做完之后,SparkContext() 最核心的地方就阅读完了,总结一下就是创建了 DAGScheduler、TaskScheduler、SchedulerBackend 三大组件。并且 SchedulerBackend 内部有两个 Endpoint,DriverEndpoint 和 ClientEndpoint,分别从来和 Worker 通信 、和 Master 通信。

下次我们来阅读 Master 处理 Driver 的注册应用程序的消息。

下面是目前的流程图:


推荐阅读
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • imx6ull开发板驱动MT7601U无线网卡的方法和步骤详解
    本文详细介绍了在imx6ull开发板上驱动MT7601U无线网卡的方法和步骤。首先介绍了开发环境和硬件平台,然后说明了MT7601U驱动已经集成在linux内核的linux-4.x.x/drivers/net/wireless/mediatek/mt7601u文件中。接着介绍了移植mt7601u驱动的过程,包括编译内核和配置设备驱动。最后,列举了关键词和相关信息供读者参考。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 如何在php文件中添加图片?
    本文详细解答了如何在php文件中添加图片的问题,包括插入图片的代码、使用PHPword在载入模板中插入图片的方法,以及使用gd库生成不同类型的图像文件的示例。同时还介绍了如何生成一个正方形文件的步骤。希望对大家有所帮助。 ... [详细]
  • 本文介绍了如何在Azure应用服务实例上获取.NetCore 3.0+的支持。作者分享了自己在将代码升级为使用.NET Core 3.0时遇到的问题,并提供了解决方法。文章还介绍了在部署过程中使用Kudu构建的方法,并指出了可能出现的错误。此外,还介绍了开发者应用服务计划和免费产品应用服务计划在不同地区的运行情况。最后,文章指出了当前的.NET SDK不支持目标为.NET Core 3.0的问题,并提供了解决方案。 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
author-avatar
BB15107669916
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有