7. TaskScheduler的启动

第五节介绍了TaskScheduler的创建,要想TaskScheduler发挥作用,必须要启动它,代码:

TaskScheduler在启动的时候,实际调用了backend的start方法,即同时启动了backend。local模式下,这里的backend是localSchedulerBackend。在TaskScheduler初始化时传入localSchedulerBackend。以LocalSchedulerBackend为例,启动LocalSchedulerBackend时向RpcEnv注册了LocalEndpoint。

7.1 创建LocalEndpoint

创建LocalEndpoint的过程主要是构建本地的Executor,见代码如下:

Executor的构建,主要包括以下步骤:

1) 创建并注册ExecutorSource。

2) 获取SparkEnv。如果是非local模式,Worker上的CoarseGrainedExecutorBackend向Driver上的CoarseGrainedExecutorBackend注册Executor时,则需要新建SparkEnv。可以修改属性spark.executor.port(默认为0,表示随机生成)来配置Executor中的RpcEnv的端口号。

3) urlClassLoader的创建。为什么需要创建这个ClassLoader?在非local模式中,Driver或者Worker上都会有多个Executor,每个Executor都设置自身的urlClassLoader,用于加载任务上传的jar包中的类,有效对任务的类加载环境进行隔离。

4) 创建Executor执行Task的线程池threadPool。此线程池用于执行任务。

5) 启动Executor的心跳线程heartbeater。此线程用于向Driver发送心跳。

此外,还包括Rpc发送消息的帧大小(10485760字节)、结果总大小的字节限制(1073741824字节)、正在运行的task的列表、设置serializer的默认ClassLoader为创建的ClassLoader等。

7.2 ExecutorSource的创建与注册

ExecutorSource用于测量系统。通过metricRegistry的register方法注册计量,这些计量信息包括threadpool.activeTasks、threadpool.completeTasks、threadpool.currentPool_size、threadpool.maxPool_size、filesystem.hdfs.write_bytes、filesystem.hdfs.read_ops、filesystem.file.write_bytes、filesystem.hdfs.largeRead_ops、filesystem.hdfs.write_ops等,ExecutorSource的实现见代码:

创建完ExecutorSource后,调用MetricsSystem的registerSource方法将ExecutorSource注册到MetricsSystem。registerSource方法使用MetricRegistry的register方法,将source注册到MetricRegistry,见代码:

7.3 Spark自身urlClassLoader的创建

获取要创建的ClassLoader的父加载器currentLoader,然后根据currentJars生成URL数组,spark.files.userClassPathFirst属性指定加载类时是否先从用户的classpath下加载,最后创建ExecutorURLClassLoader或者ChildExecutorURLClassLoader,见代码:

MutableURLClassLoader或者ChildFirstURLClassLoader实际上都继承了URLClassLoader,见代码:

如果需要REPL交互,还会调用addReplClassLoaderIfNeeded创建replClassLoader,见代码:

7.4 启动Executor的心跳线程

Executor的心跳由startDriverHeartbeater启动。Executor心跳线程的间隔由属性spark.executor.heartbeatInterval配置,默认是10000毫秒。此外,超时时间是30秒,超时重试次数是3次,重试间隔是3000毫秒。此线程从runningTasks获取最新的有关Task的测量信息,将其与executorId、blockManagerId封装为Heartbeat消息,向HearbeatReceiverRef发送Heartbeat消息。

这个心跳线程的作用是什么呢?其作用有两个:

  • 更新正在处理的任务的测量信息;
  • 通知BlockManagerMaster,此Executor上的BlockManager依然活着。

下面对心跳线程的实现详细分析下:

初始化TaskSchedulerImpl后会创建心跳接收器HeartbeatReceiver。HeartbeatReceiver接收所有分配给当前Driver Application的Executor的心跳,并将Task、Task计量信息、心跳等交给TaskSchedulerImpl和DAGScheduler作进一步处理。创建心跳接收器的代码如下:

HeartbeatReceiver在收到心跳信息后,会调用TaskScheduler的executorHeartbeatReceived方法,代码如下:

executorHeartbeatReceived的实现代码如下:

这段程序通过遍历accumUpdates,依据taskIdToTaskSetId找到TaskSetManager。然后将taskId、TaskSetManager.stageId、TaskSetManager.taskSet.stageAttemptId、accInfos封装到类型为Array[(Long, Int, Int,Seq[AccumulableInfo])]的数组accumUpdatesWithTaskIds中。最后调用了dagScheduler的executorHeartbeatReceived方法,其实现如下:

dagScheduler将executorId、accumUpdates封装为SparkListenerExecutorMetricsUpdate事件,并post到listenerBus中,此事件用于更新Stage的各种测量数据。最后给BlockManagerMaster持有的BlockManagerMasterEndpoint发送BlockManagerHeartbeat消息。BlockManagerMasterEndpoint在接收到消息后会匹配执行heartbeatReceived方法。heartbeatReceived最终更新BlockManagerMaster对BlockManager的最后可见时间(即更新BlockManagerId对应的BlockManagerInfo的_lastSeenMs)。

Spark源码剖析 - SparkContext的初始化(七)_TaskScheduler的启动的更多相关文章

  1. Spark源码剖析 - SparkContext的初始化(二)_创建执行环境SparkEnv

    2. 创建执行环境SparkEnv SparkEnv是Spark的执行环境对象,其中包括众多与Executor执行相关的对象.由于在local模式下Driver会创建Executor,local-cl ...

  2. Spark源码剖析 - SparkContext的初始化(三)_创建并初始化Spark UI

    3. 创建并初始化Spark UI 任何系统都需要提供监控功能,用浏览器能访问具有样式及布局并提供丰富监控数据的页面无疑是一种简单.高效的方式.SparkUI就是这样的服务. 在大型分布式系统中,采用 ...

  3. Spark源码剖析 - SparkContext的初始化(十)_Spark环境更新

    12. Spark环境更新 在SparkContext的初始化过程中,可能对其环境造成影响,所以需要更新环境,代码如下: SparkContext初始化过程中,如果设置了spark.jars属性,sp ...

  4. Spark源码剖析 - SparkContext的初始化(一)

    1. SparkContext概述 注意:SparkContext的初始化剖析是基于Spark2.1.0版本的 Spark Driver用于提交用户应用程序,实际可以看作Spark的客户端.了解Spa ...

  5. Spark源码剖析 - SparkContext的初始化(五)_创建任务调度器TaskScheduler

    5. 创建任务调度器TaskScheduler TaskScheduler也是SparkContext的重要组成部分,负责任务的提交,并且请求集群管理器对任务调度.TaskScheduler也可以看作 ...

  6. Spark源码剖析 - SparkContext的初始化(八)_初始化管理器BlockManager

    8.初始化管理器BlockManager 无论是Spark的初始化阶段还是任务提交.执行阶段,始终离不开存储体系.Spark为了避免Hadoop读写磁盘的I/O操作成为性能瓶颈,优先将配置信息.计算结 ...

  7. Spark源码剖析 - SparkContext的初始化(九)_启动测量系统MetricsSystem

    9. 启动测量系统MetricsSystem MetricsSystem使用codahale提供的第三方测量仓库Metrics.MetricsSystem中有三个概念: Instance:指定了谁在使 ...

  8. Spark源码剖析 - SparkContext的初始化(四)_Hadoop相关配置及Executor环境变量

    4. Hadoop相关配置及Executor环境变量的设置 4.1 Hadoop相关配置信息 默认情况下,Spark使用HDFS作为分布式文件系统,所以需要获取Hadoop相关配置信息的代码如下: 获 ...

  9. Spark源码剖析 - SparkContext的初始化(六)_创建和启动DAGScheduler

    6.创建和启动DAGScheduler DAGScheduler主要用于在任务正式交给TaskSchedulerImpl提交之前做一些准备工作,包括:创建Job,将DAG中的RDD划分到不同的Stag ...

随机推荐

  1. P3723 [AH2017/HNOI2017]礼物

    题目链接:[AH2017/HNOI2017]礼物 题意: 两个环x, y 长度都为n k可取 0 ~ n - 1      c可取任意值 求 ∑ ( x[i] - y[(i + k) % n + 1] ...

  2. 【CF671D】Roads in Yusland(贪心,左偏树)

    [CF671D]Roads in Yusland(贪心,左偏树) 题面 洛谷 CF 题解 无解的情况随便怎么搞搞提前处理掉. 通过严密(大雾)地推导后,发现问题可以转化成这个问题: 给定一棵树,每条边 ...

  3. 【Nowcoder71E】组一组(差分约束,最短路)

    [Nowcoder71E]组一组(差分约束,最短路) 题面 Nowcoder 题解 看到二进制显然就直接拆位,那么区间的按位或和按位与转成前缀和之后,可以写成两个前缀和的值的差的大小关系,那么直接差分 ...

  4. ZJOI 2019 划水记

    作为一个极其蒟蒻的OIer,虽然没有省选资格但还是去见见世面. ZJOI2019一试是在浙江省镇海中学.听名字就很霸气. 学习OI的最后一年,记录下一些事情,即使最终走到最后也一无所获,也是一段美好的 ...

  5. linux deb系 rpm系 配置路由

    deb: 添加默认路由:route add default gw 8.46.192.1 添加网段路由:route add -net 8.46.0.0/19 gw 8.46.192.1 删除路由:把 a ...

  6. [HEOI2014]逻辑翻译(分治)

    题目描述 在人类的神经系统中,每个信号都可以用?1或+1来表示.这些信号组合起来最后形成 了喜怒哀乐,酸甜苦辣,红黄绿蓝等各种各样的复杂信息.纳米探测科技的突破让生物学家 可以测量大脑中特定区域的完整 ...

  7. javascript之判断专题

    javascript有数组,对象,函数,字符串,布尔,还有Symbol,set,map,weakset,weakmap. 判断这些东西也是有很多坑,像原生的typeof,instanceOf有一些bu ...

  8. 省选前的JOI

    RT,发现找不到题,于是又开了新坑 JOI特色:重思考,代码难度(相比NOI系列)基本没有 (省选前到处挖坑2333) JOI 2017 Final 焚风现象 差分,莫得了 (不是看到200ms就tm ...

  9. react-native中使用长列表

    React Native 提供了几个适用于展示长列表数据的组件,一般而言我们会选用FlatList或是SectionList. FlatList组件用于显示一个垂直的滚动列表,其中的元素之间结构近似而 ...

  10. Linux:在文件最后一列添加递增数(awk,cat函数)

    假设有文件file1.txt: aa eeeee bb eeeee cc eeeee dd eeeee 先修改为: aa eeeee 1 bb eeeee 2 cc  eeeee3 dd eeeee ...