阅读这篇文章,你应该得到面试中有可能会问到的几个问题的答案:
- spark的运行模式有几种?
- 这几种运行模式在调度上有什么差别?
思路
其实简单使用过spark的童鞋们都应该知道spark的运行模式就是这几种,一些人也能大致说出不同运行模式的差别,这里我们从源码的角度分析一下运行模式的不同会引起什么样的任务调度
local模式
1、定义
spark的local模式是在本地起多个Thread,每个thread相当于一个executor,来模拟spark的并行运行模式,在实际项目中常用的有两种写法:
- local[N],启动指定个数的线程数;
- local[*], 根据本地环境启动可以启动的最大线程数
2、调度 (LocalSchedulerBackend)
了解了定义之后,我们自然想知道指定了这个模式以后,它的运行方式是什么样的
可以看到LocalSchedulerBackend继承了两个调度类
- SchedulerBackend 调度后端
- ExecutorBackend 执行后端
2.1、SchedulerBackend
对于调度后端来说,只负责调度整个任务的各个阶段,分别为开始阶段、执行阶段和结束阶段,相应的,对于这个接口类只定义了这几个方法:
- start():任务开始方法
- stop():终止任务方法
- reviveOffers() :复活executor的方法
- defaultParallelism(): 默认的任务并行度
- killTask():kill task方法,接收4个参数:taskId、executorId、是否中断线程、失败原因
- isReady()
- applicationId():获取yarn上的applicationId
- applicationAttemptId():失败后重试的id
- getDriverLogUrls():log日志
- maxNumConcurrentTasks():当前能并行提交的最大线程数
2.2、ExecutorBackend
用于将executor上的数据的更新发送给集群的调度模块
了解了基类以后,接下来进入正题
这里主要看LocalEndpoint这个类,因为这是local模式特有的实现过程,也是local和其他运行模式的最大区别
主要看这一行的代码:
这里指定本地的driver和hostname:localhost之后,直接调用Executor类去构建executor,这里我们就发现了最大模式之间的最大差别就是构建Executor类的方式。
- 这个类里面,先做了一系列的参数校验,包含hostname,是否本地模式等。。。
- 然后为指定的executor申明线程池,用于后面的task任务:如下图所示:
cluster模式 (CoarseGrainedSchedulerBackend)
1、定义
spark框架为了和第三方resource结合,定义的集群任务调度模块,常见的resource有三种:
- yarn
- mesos
- kubernetes
这里我不展开说这几个具体的模式,后续会有专门的文章说这块的东西,本来spark也把这块做了一个单独的模块
2、调度
Standalone模式(StandaloneSchedulerBackend)
1、定义
spark框架自带的集群任务调度模块