Spark Worker源码

目录

 

1、概述

2、LaunchDriver

3、LaunchDriver

4、总结


1、概述

worker肯定是实现RPC通信的,否则别人没法给你发消息。他继承的是ThreadSafeRpcEndpoint,ThreadSafeRpcEndpoint是线程安全的,意味着处理一条消息完成后再处理下一个消息。换句话说,在处理下一条消息时,可以看到对ThreadSafeRpcEndpoint的内部字段的更改,并且ThreadSafeRpcEndpoint中的字段不需要是volatile或等效的。但是,不能保证同一个线程将为不同的消息执行相同的ThreadSafeRpcEndpoint。即顺序处理消息,不能同时并发处理。

Worker本身在实际运行的时候是作为一个进程,他会接收master的指令,有几个非常重要的指令,如LaunchExecutor,LaunchDriver等。这两个指令是Schedule进行资源调度(Master的schedule方法中)的时候发送的。

2、LaunchDriver

Worker在收到Driver发送的LaunchDriver类型的信息后。

(1)首先首先打印一个日志,master传进来的时候肯定会告诉你driverId的,然后new 一个DriverRunner,然后把这个实例通过driverId交给一个HashMap数据结构val drivers = new HashMap[String, DriverRunner]。key就是driverId,value就是DriverRunner。这个数据结构非常重要,因为我们在worker上可能启动很多Executor,需要根据ExecutorId管理具体的DriverRunner,DriverRunner内部通过线程的方式启动了另外一个进程,所以可以简单理解DriverRunner是Driver所在进程中本身的process,这个就是一个代理模式。

(2)管理Driver的执行,包括在Driver失败的时候自动重启,要是在Standalone的模式下。失败是否重试是看DriverDescription中的supervise是否为true,如果指定了这个参数为true,driver在失败的时候worker会负责启动这个Driver

(3)构建好DriverRunner实例,并且已经将其加入到drivers中后,调用DriverRunner的start方法。在start方法中通过一个线程启动Driver,并管理Driver,线程运行的时候run方法会被执行。

在run方法中有个prepareAndRunDriver用于准备Driver需要的jar并运行Driver

(4)在prepareAndRunDriver方法中,会创建工作目录,下载jar包到本地,并封装好Driver的启动Command,通过buildProcessBuilder来启动Driver。

driverDesc.command这个指定他启动的时候应该运行什么类,就是类的入口。driverDesc是Master远程发送过来的,为CoarseGrainedExecutorBackend

进入到runDriver方法中,有个initialize方法,里面重定向输出和error,将stout和stderr重定向到baseDir下,这样就可以通过log看一下曾经执行的情况。

然后执行runCommandWithRetry,在参数中会构造ProcessBuilderLike。ProcessBuilderLike在apply的时候就new ProcessBuilderLike,在这里面processBuilder.start()

在runCommandWithRetry方法中,会一直循环,孵化出一个进程,有个方法这个是阻塞的,言外之意就是当他回复过来的时候估计就有问题了,那就判断一下

(5)在prepareAndRunDriver方法中启动Driver之后,如果运行出状况了,出状况后会给自己发一个消息

(6)在这里不同的情况打印log日志,最关键的是sendToMaster(driverStateChanged)发送给master。发送的类型是DriverStateChanged

(7)到Master方法中。master收到这个消息后就把他remove掉,是从自己的内存数据结构中remove,同时把这个driver曾经占用的数据,还有持久化的都remove,然后再次发消息给worker确认下,因为发生了资源的变动再次进行schedule

(8)回到Worker中,start之后记录耗了多少内存CPU

3、LaunchDriver

Worker在收到Driver发送的LaunchExecutor类型的信息后首先new 一个ExecutorRunner,然后start。过程与启动Driver类似,就不细说。

在ExecutorRunner的start方法中会通过一个线程启动Executor,并管理Executor,线程运行的时候run方法会被执行。

fetchAndRunExecutor方法中类似driver中创建该executor工作目录,下载运行的jar,开启执行application的进程executor。并向worker发送ExecutorStateChanged的事件通知,

worker先向自己发送ExecutorStateChanged的消息

在start方法之后,记录耗了多少内存CPU,然后向master发送接收到的ExecutorStateChanged的事件通知

 

4、总结

driver进程就是executor进程;ExecutorBackend是进程名称,standalone模式下是CoarseGrainedExecutorBackend。在CoarseGrainedExecutorBackend中有我们的Executor对象本身,Executor和ExecutorBackend是一对一的关系,就是一个ExecutorBackend进程里面有一个Executor,在Executor内部是通过线程池并发处理的方式来处理Spark提交过来的Task。

注意:Executor启动之后要向我们的driver注册。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值