Spark源码学习:sparkContext的初始化分析

spark可以运行在本地模式local下,可以运行在yarn和standalone模式下,但是本地程序是通过什么渠道和这些集群交互的呢?那就是sparkContext,他在spark生态系统中的作用不言而喻,绝对是最重要的,整体架构如图所示:

这里我们简单的来剖析一下,sparkContext在初始化最重要的流程和大致框架。spark代码第一句都是先创建sparkConf之后作为参数传递给sparkContext在进行创建sc,之后的一切操作都离不开sparkContext。

val conf = new SparkConf().setAppName(appName).setMaster(master)
sc=new SparkContext(conf)

在debug模式下进入源代码。

可以看到这里的sparkContext使用sparkConf作为参数来进行传递参数。变量allowMultipleContext是用来决定是否在spark中指运行一个任务,markPartiallyContructed来确保实例的唯一性。

上面是对sparkConf进行复制之后,然后对配置信息进行校验。上面的代码显示spark运行必须指定master和name,否则就会抛出异常,结束初始化过程,在后面我们会看到master是用来设置部署模式,name用来指定程序名称,相对简单。

下面重要的是sparkEnv的初始化,sparkEnv是spark的执行环境对象,包括很多与Executor执行相关的对象。在local模式下Driver会创建Executor,local-cluster部署模式或者standalone部署模式下worker另起CoarseGrainedExecutorBackend进程中创建executor,继而创建taskRunner方法,运行runtask运行任务,这个方法会有自己的具体实现类,shufflemaptask和resulttask有具体的实现。所以sparkEnv存在于driver或者CoarseGrainedExecutorBackend进程中。代码如下:

我们进入createDriverEnv方法,它隶属于SparkEnv的方法。主要保存spark运行时环境变量。这里阐述最重要的变量初始化,至于什么页面监控之类的就不看了。

(1) Akka的分布式消息系统actorSystem的初始化。

(2) 创建map任务输出跟踪器mapoutputTracker,主要就是跟踪map任务把数据结果写到哪里去了,reduce也可以去取数据map,reduce,shuffle都有自己所对应的ID,着重介绍一下MapOutputTrackerMaxter,它内部使用mapStatuses来维护跟中map任务的输出状态,这个数据结构是一个map,其中key对应shufleID,value存储各个map任务对应的状态信息mapStatus。由于mapStatus是由blockmanagerid(key)和bytesSize(value)组成,key是表示这些计算的中间结果存放在那个blockManager,value表示不同的reduceID要读取的数据大小这时reduce就知道从哪里fetch数据,并且判断数据的大小(和0比较来确保确实获得了数据)。

driver和executor处理mapOutputtTrackermMaster的方式不同:

Driver:创建mapOutputtTrackermMaster,然后创建mapOutputtTrackermMasterActor,并且注册到ActorSystem.

Executor:创建mapOutputtTrackerm,并从ActorSystem中找到mapOutputtTrackermMasterActor。

有那么多的executor,当然就有跟多的mapTask,那driver是怎样知道各个mapTask的执行任务信息呢?那就靠我们上面的mapOutputtTrackermMasterActor啦,哈哈。map任务的状态就是有Executor向持有mapOutputtTracker-MasterActor来发送消息,把map任务状态同步到mapOutputtTracker的mapstatuses上去。问题又来了,executor怎样找到mapOutputtTrackermMasterActor呢?那就靠registe'OrLookup函数啦,它后台使用ActorSystem提供的分布式消息机制实现的。

那就来看看具体的代码吧:

(3)实例化ShuffleManager。它主要是负责管理本地和远程的block的shuffle操作。ShuffleManager通过反射机制来生成默认的SortShuffleManager。可以通过修改spark.shuffle.manager设置为hash来显示的控制使用HashShuffle-Manager。这里的sort主要是指在shuffle中的key-value,key是默认排序好的。具体代码如下:

(4)块儿传输服务BlockTransferServervice。这里默认的是NettyBlockTransferServervice。可以通过配置属性spark.shuffle.blockTransferService使用NioBlockTransferService。NettyBlockTransferServervice使用Netty提供的异步事件驱动网络应用框架,提供web服务及客户端,获取远程节点上的Block集合。代码如下:

(5)创建BlockManagerMaster。它是负责block的管理和协调,具体的操作是依赖于BlockManagerMaster-Actor,因为它需要与Executor上的BlockManager通过Actor进行通信。(这里的Endpoint相当于Actor)

(6) 创建BlockManager。他主要运行在worker节点上。虽然这里创建了,但是只有在他的init初始化函数之后才是有效的。

(7)创建广播管理器BroadcastManager。主要是负责把序列化时候的RDD,job以及shuffleDependence等,以及配置信息存储在本地,有时候还会存储到其他的节点以保持可靠性。

(8) 创建存储管理器CacheManager。他主要用于缓存RDD某个分区计算的中间结果,缓存计算结果在迭代计算的时候发生。他很有用,可以减少磁盘IO,加快执行速度。

(9) HTTP文件服务器httpFileServer。退工对jar以及其他文件的http访问。例如jar包的上传等等。他的端口号由spark.fileserver.port来配置,默认情况下是0,表示随机生成端口号。

(10)最后创建测量系统MetricsSystem,是spark的测量系统,不用深究,这里我们不管他。

上面的10条主要说的是sparkEnv的创建,执行环境也就刚刚初始化完毕,核心的核心还没开始呢。

具体的变量创建等等下篇我们再来介绍。

spark的sparkContext初始化中的sparkEnv相关的概念以及重要的组成部分在上一部分简单的介绍 ,这篇简单的介绍一下和DAGScheduler,taskSetManager,SchedulerBackend,taskScheduler等等一些和sparkContext初始化相关的概念,这里讨论的是重中之重,下面就来大体的来看看。首先看一下最重要最核心的一个片段:

在上面的一片代码中我们可以看到,首先是SparkContext.createTaskScheduler来创建SchedulerBackend以及TaskScheduler。理解清楚这两个概念极为重要。首先来看看SchedulerBackend,从源码的注释上可以知道Scheduler-Backend仅仅是后台调度系统的一个抽象接口,目前在1.5.2接口有四个实现类。TaskScheduler主要是底层人物调度接口,仅仅是有一个实现类TaskSchedulerImpl。TaskSchedulerImpl就是通过schedulerBackend来在不同的cluster上调度任务,例如可以设置变量isLocal为true来使用lLocalBackend。

createTaskScheduler方法的两个参数一个sc一个master,master主要就是用来匹配对应的运行模型,例如:

上面的这个model代表的是standalone模式,SparkDeploySchedulerBackend就是standalone的运行模式。接下来进入initlalize方法看看:

上面的这个初始化方法就是在taskSchedulerImpl下初始化的,会发现在任务的调度模式中选择了两种调度方式,先进先出和公平调度方法。

继而开始了taskscheduler的start方法,进入taskSchedluer的run方法,是一个抽象接口,抽象接口的实现task-SchedluerImpl的run方法来看看。backend就是schedulerBackend后台,那么这个start方法是有4个实现的start方法。

那么就加入loacl模式下的LocalBackend代码:

  1. private[spark] class LocalBackend(
  2. conf: SparkConf,
  3. scheduler: TaskSchedulerImpl,
  4. val totalCores: Int)
  5. extends SchedulerBackend with ExecutorBackend with Logging {
  6. private val appId = "local-" + System.currentTimeMillis
  7. var localEndpoint: RpcEndpointRef = null
  8. override def start()
  9. override def stop()
  10. override def reviveOffers()
  11. override def defaultParallelism()
  12. override def killTask(taskId: Long, executorId: String, interruptThread: Boolean)
  13. override def statusUpdate(taskId: Long, state: TaskState, serializedData: ByteBuffer)
  14. override def applicationId(): String = appId

这里还有一部分中最关键的DAGScheduler的创建相关的代码,下篇进行价绍。

sparkContext之一:sparkContext的初始化分析的更多相关文章

  1. JVM学习四:JVM之类加载器之初始化分析

    在经过了前面的加载  和 连接分析之后,这一节我们进入重要的初始化分析过程: 一.认识初始化 初始化:这个似乎与上面的初始化为默认值有点矛盾,我们再看一遍:为累的静态变量赋予正确的初始值,上面是赋予默 ...

  2. Ztack学习笔记(2)-系统初始化分析

    main函数先执行初始化工作,包括硬件.网络层.任务等的初始化. 一 系统初始化 系统初始化函数主要完成内存分配.消息队列头.定时器.电源管理.任务系统及内存栈等的初始化,具体如下代码所示: //os ...

  3. cc2530操作任务系统初始化分析

    操作系统任务初始化void osalInitTasks( void ){ uint8 taskID = 0; // 分配内存,返回指向缓冲区的指针 tasksEvents = (uint16 *)os ...

  4. Android 5.0 Phone初始化分析

    已经更新至个人blog:http://dxjia.cn/2015/07/android-5-0-phone-init-analysis/ persistent属性 要想了解phone的框架,首先需要了 ...

  5. socket相关的开机初始化分析

    针对内核3.9 系统开启时,会使用init/main.c,然后再里面调用kernel_init(),在里面会再调用do_basic_setup(),调用do_initcalls(),调用do_one_ ...

  6. STM32_3 时钟初始化分析

    在startup文件中,调用了2个函数,一个是System_Init, 另一个是main. System_Init()在system_stm32f10x.c 这个文件中,先看一下时钟树,再分析一下这个 ...

  7. Android编译系统环境过程初始化分析【转】

    本文转载自:http://blog.csdn.net/luoshengyang/article/details/18928789 Android源代码在编译之前,要先对编译环境进行初始化,其中最主要就 ...

  8. 列表初始化 分析initializer_list<T>的实现

    列表初始化(1)_统一初始化 1. 统一初始化(Uniform Initialization) (1)在C++11之前,很多程序员特别是初学者对如何初始化一个变量或对象的问题很容易出现困惑.因为可以用 ...

  9. OSharp DbContent初始化分析

    DBContent初始化 —— 关联Entity查找 一.      关联到具体的Entity 二.      通过EntityTypeConfiguration 关联到DbContent 三.    ...

随机推荐

  1. 简学lingo(四)——实例篇

    本片将会接着上篇实例来写,如要參照能够看下上篇的http://blog.csdn.net/yzu_120702117/article/details/38453791 如有句法上的问题能够參照我之前总 ...

  2. Hadoop学习笔记(一)——Hadoop体系结构

    HDFS和MapReduce是Hadoop的两大核心. 整个Hadoop体系结构主要是通过HDFS来实现分布式存储的底层支持的,而且通过MapReduce来实现分布式并行任务处理的程序支持. 一.HD ...

  3. kubernetes调度之 PriorityClass

    系列目录 kubernetes支持多种资源调度模式,前面讲过简单的基于nodeName和nodeSelector的服务器资源调度,我们称之为用户绑定策略,下面简要描述基于PriorityClass的同 ...

  4. hdu1878欧拉回路(DFS+欧拉回路)

    欧拉回路 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  5. unity3d开发的android应用中增加AD系统的详细步骤

    unity3d开发的android应用中增加AD系统的详细步骤 博客分类: Unity3d unity3d  Unity3d已经支持android,怎样在程序里增加admob?  试了一下,确实能够, ...

  6. 02-合并frame

    进入IJKMediaPlayer工程--->

  7. 2018.11.23-day26 面向对象(终结)

    1.私有成员不能被继承2.装饰器方法--(类方法&静态方法)3.装饰器--property方法4.反射

  8. github for unity

  9. UIBezierPath(转)

    @import url(/css/cuteeditor.css); @import url(/css/cuteeditor.css); @import url(http://i.cnblogs.com ...

  10. ARM编译器中预定义的宏

    arm系列目前支持三大主流的工具链,realview的armcc,iar ewarm的iccarm,gnu的gcc,编译器在编译的时候会预定义一些宏,这些宏在工程中起到不可或缺的作用. 例如 /* d ...