大数据IMF传奇行动绝密课程第33课:Spark Executor内幕彻底解密

来源:互联网 发布:简述分组转发算法 编辑:程序博客网 时间:2024/04/29 00:35

Spark Executor内幕彻底解密

一、Spark Executor工作原理图
二、ExecutorBackend注册源码揭秘
三、Executor实例化内幕
四、Executor具体是如何工作的?

为什么不重新启动一个进程
worker不能计算、worker里面可能有其他Executor,如果其中一个崩溃了,其他也崩溃了。

图33-1 Executor内部运行原理和流程

一、Spark Executor工作
1、需要特别注意是在CoarseGrainedExecutorBackend启动时向Driver注册Executor其实质是注册ExecutorBackend实例和Executor实例之间没有直接的关系
2、CoarseGrainedExecutorBackend是Executor运行所在的进程名称,Executor才是真正处理Task的对象,Executor内部是通过线程池的方式来完成Task的计算的
3、CoarseGrainedExecutorBackend和Executor是一一对应的
4、CoarseGrainedExecutorBackend是一个消息通信体(其实现了ThreadSafeRpcEndpoint),可以发送信息给Driver并可以接收Driver中发过来的指令,例如启动Task等;
5、在Driver进程中,有两个至关重要的Endpoint,
a)ClientEndpoint:主要负责向Master注册当前程序,是AppClient的内部成员
b)DriverEndpoint:这是整个程序运行时候的驱动器,是CoarseGrainedSchedulerBackend的内部成员
6、在Driver中通过ExecutorData封装并注册ExecutorBackend的信息到Driver的内存数据结构executorDataMap中
private[cluster] class ExecutorData(
val executorEndpoint: RpcEndpointRef,
val executorAddress: RpcAddress,
override val executorHost: String,
var freeCores: Int,
override val totalCores: Int,
override val logUrlMap: Map[String, String]
) extends ExecutorInfo(executorHost, totalCores, logUrlMap)

7、实际在执行的时候DriverEndpoint会把信息写入CoarseGrainedSchedulerBackend的内存数据结构executorDataMap中,所以说最终是注册给了CoarseGrainedSchedulerBackend,也就是说CoarseGrainedSchedulerBackend掌握了为当前程序分配的所有的ExecutorBackend进程,而在每一个ExecutorBackend进行实例中会通过Executor对象来负责具体Task的运行。在运行的时候使用synchronized关键字来保证executorMapData安全的并发写操作。

8、CoarseGrainedExecutorBackend收到DriverEndpoint发送过来的RegisteredExecutor消息后会启动Executor实例对象,而Executor实例对象是事实上负责真正Task计算的;

二、Executor具体是如何工作的:
1、当Driver发送过来Task的时候,其实是发送给了CoarseGrainedExecutorBackend则个RpcEndpoint,而不是直接发送给了Executor(Executor由于不是消息循环体,所以永远也无法直接接收远程发过来的信息)

case LaunchTask(data) =>
if (executor == null) {
logError(“Received LaunchTask command but executor was null”)
System.exit(1)
} else {
val taskDesc = ser.deserializeTaskDescription
logInfo(“Got assigned task ” + taskDesc.taskId)
executor.launchTask(this, taskId = taskDesc.taskId, attemptNumber = taskDesc.attemptNumber,
taskDesc.name, taskDesc.serializedTask)
}

2、ExecutorBackend在收到Driver中发送来的消息后会通过调用launchTask来交给Executor去执行

0 0
原创粉丝点击