spark 获取广播变量_Spark原理分析

13aca8d4fa0c5ec886c552323781c1b4.png

主要包括

  • 学习目标
  • 核心组件的运行机制(Master,Worker,SparkContext等)
  • 任务调度的原理
  • 个人愿景

阶段性总结

在拉勾学习的4个月中,从一名大数据小白到现在已经掌握了大数据生态的很多组件:HDFS,MapReduce,Hive,Hbase,Impala等,这个课程给我带来了满满的收获,课程的内容和深度也设计的比较合理,对于目前正在工作的我来说,学习大数据课程起来比较有节奏,没有走太多弯路。除了技术大牛的讲师外,还有一群有着共同目标的同学,很多问题在大家的讨论下也加深了对知识点的记忆,还有我特别要感谢的是:小嘟导师,我比较喜欢钻牛角尖,有时候被一个细节的不理解苦苦思索,最后请教小嘟,她基本都是秒回,然后给我分析问题,真的很nice.

核心组件的运行机制

Spark 执行任务的原理:

1bfe7874050bcb4a88cfb68a76ed8e22.png
spark任务执行原理图

Spark on Yarn:

Cluster模型:

139af455e996e4862b8fd7403133d812.png
Cluster模型图

Client模型:

752518365d51ed6ecb8e82abec526e17.png
Client

Master Worker通信原理

20f00ede376f64e40d0f169323539e0a.png
Spark通信原理

RpcEnv是RPC的环境对象,管理着整个 RpcEndpoint 的生命周期,其主要功能有:根据name或uri注册endpoints、管理各种消息的处理、停止endpoints。其中RpcEnv只能通过RpcEnvFactory创建得到。 RpcEnv中的核心方法:

// RpcEndpoint 向 RpcEnv 注册 
def setupEndpoint(name: String, endpoint: RpcEndpoint): RpcEndpointRef
// 根据参数信息,从 RpcEnv 中获得一个远程的RpcEndpoint 
def setupEndpointRef(address: RpcAddress, endpointName: String): RpcEndpointRef

RpcEndpoint**:是一个特质,**表示一个消息通信体,可以接收、发送、处理消息

生命周期为:construct(构建)->onStart(运行)->receive*(接收消息)->onStop(停止)

Spark的MasterWorker都实现了RpcEn**dpoint这个特征**

RpcEndPointRef:RpcEndPointRef是对远程RpcEndpoint的一个引用,当需要向一个具体的RpcEndpoint发送消息时,需要获取到该RpcEndpoint的引用,然后通过该引用发送消息。

备注*:在Spark源码中,看到private[spark],意思是在spark的包是私有的,除了在spark之外包不能使用

SparkEnv

SparkEnv是Spark计算层的基石,不管是Driver还是Executor,都需要依赖SparkEnv来进行计算,它是Spark的运行环境对象。

看下SparkEnv源码中的构造方法:

class SparkEnv (
    val executorId: String,---------------------->Executor 的id
    private[spark] val rpcEnv: RpcEnv, ---------------------->通信组件,使SparkEnv具备通信能力
    val serializer: Serializer,
    val closureSerializer: Serializer,
    val serializerManager: SerializerManager,---------------------->序列化管理器
    val mapOutputTracker: MapOutputTracker,---------------------->map阶段输出追踪器
    val shuffleManager: ShuffleManager,---------------------->Shuffle管理器
    val broadcastManager: BroadcastManager,---------------------->广播管理器
    val blockManager: BlockManager,---------------------->块管理器
    val securityManager: SecurityManager,---------------------->安全管理器
    val metricsSystem: MetricsSystem,---------------------->度量系统
    val memoryManager: MemoryManager,---------------------->内存管理器
    val outputCommitCoordinator: OutputCommitCoordinator,---------------------->输出提交协调器
    val conf: SparkConf

从SparkEnv的成员变量可以验证,SparkEnv包含了Spark运行的很多重要组件

SparkEnv的单例对象:

3d7f927b5f1a6b18b06afad24d8ff0c1.png

SparkEnv单例对象在JVM是单例的,集群情况下Driver和Executor独自的jvm进程,它们都有各自的SparkEnv单例对象

SparkContext

SparkContext使Spark功能的主要入口点,主要代标与spark的连接,能够用来在集群上创建RDD、累加器、广播变量。每个JVM里之恶能存在一个处于激活状态的SparkContext,在创建新的SparkContext之前必须调用stop()来关闭之前的SparkContext。

源码里SparkContext的一些成员变量

  //spark的配置,本质上是一个并行map集合
  private var _conf: SparkConf = _
  private var _eventLogDir: Option[URI] = None
  private var _eventLogCodec: Option[String] = None
  private var _listenerBus: LiveListenerBus = _
  //构建整个环境,从上面分析的SparkEnv源码可知,SparkContext具备通信,广播,度量等能力
  private var _env: SparkEnv = _
  //状态追踪
  private var _statusTracker: SparkStatusTracker = _
  //进度条
  private var _progressBar: Option[ConsoleProgressBar] = None
  private var _ui: Option[SparkUI] = None
  private var _hadoopConfiguration: Configuration = _
  private var _executorMemory: Int = _
  private var _schedulerBackend: SchedulerBackend = _
  private var _taskScheduler: TaskScheduler = _
  //通信
  private var _heartbeatReceiver: RpcEndpointRef = _
  @volatile private var _dagScheduler: DAGScheduler = _
  //应用id
  private var _applicationId: String = _
  private var _applicationAttemptId: Option[String] = None
  private var _eventLogger: Option[EventLoggingListener] = None
  //动态资源分配
  private var _executorAllocationManager: Option[ExecutorAllocationManager] = None
  //资源的清理
  private var _cleaner: Option[ContextCleaner] = None
  private var _listenerBusStarted: Boolean = false
  private var _jars: Seq[String] = _
  private var _files: Seq[String] = _
  private var _shutdownHookRef: AnyRef = _
  private var _statusStore: AppStatusStore = _

SparkContext初始化

df35b2d97b4ede575d89337ec71d8af4.png

任务调度原理

调度的三大组件启动流程

  • DAGScheduler(高层调度器,class):负责将DAG拆分成不同Stage(TaskSet),然后提交给TaskScheduler进行具体处理
  • TaskScheduler(底层调度器,trait,只有一种实现TaskSchedulerImpl):负责实际每个具体Task的物理调度执行
  • SchedulerBackend(trait):有多种实现,分别对应不同的资源管理器
    • Standalone模式下,其实现为:StandaloneSchedulerBackend
    • 对应Yarn
    • 。。。。

启动流程方法栈:

val (sched, ts) = SparkContext.createTaskScheduler(this, master, deployMode)
------>SparkContext.createTaskScheduler#
-----------> case SPARK_REGEX(sparkUrl) =>
-----------> val scheduler = new TaskSchedulerImpl(sc)//创建scheduler
-----------> val backend = new StandaloneSchedulerBackend(scheduler, sc, masterUrls)
----------->scheduler.initialize(backend)
----------------->TaskSchedulerImpl#initialize //初始化
-----------------------> this.backend = backend//赋值SchedulerBackend
-----------------------> schedulableBuilder={match}//选择调度策略
----------->(backend, scheduler)
------>_schedulerBackend = sched//给_schedulerBackend赋值
------>_taskScheduler = ts//给_taskScheduler赋值
------>_dagScheduler = new DAGScheduler(this)//_dagScheduler
------>_taskScheduler.start()//启动_taskScheduler
----------->TaskSchedulerImpl#start()
----------------->backend.start()//启动backend
----------------------->StandaloneSchedulerBackend#start//启动
---------------------------->super.start()
----------------------------------->CoarseGrainedSchedulerBackend#start
--------------------------------------->driverEndpoint = createDriverEndpointRef(properties)//创建Driver的Endpoint
---------------------------------------------->DriverEndpoint#onStart//自动执行onStart
---------------------------------------------------->reviveThread.scheduleAtFixedRate//间隔1s执行
---------------------------------------------------------->  Option(self).foreach(_.send(ReviveOffers))//自己给自己发消息
---------------------------------------------->case ReviveOffers =>makeOffers()//接收搭配ReviveOffers这个消息触发
---------------------------------------------->makeOffers()//调度的是底层的资源 只有资源没有任务  offer-》Taskschedule(负责将底层的资源和任务结合起来)
-------------------------------------------------->scheduler.resourceOffers(workOffers)//将集群的资源以Offer的方式发给上层的TaskSchedulerImpl。
-----------------> client = new StandaloneAppClient(sc.env.rpcEnv, masters, appDesc, this, conf)//创建 StandaloneAppClient
----------------->client.start()
----------------->ClientEndpoint#oNstart=>registerWithMaster(1)//应用程序向 Master 注册

根据以上的方法执行栈可以得出:SparkContext初始化的过程中完成了TaskScheduler,SchedulerBackend,DAGScheduler三个组件的初始化,在初始化的过程中会向master发送注册消息,Driver会周期性的给自己发送消息,调度底层的资源,将集群中的资源以offer的形式发给TaskSchedulerImpl,TaskSchedulerImpl拿到DAGScheduler分配的TaskSet,给task分配资源

作业执行流程(追源码绘制):

0dcc748683262bb8c925f03cdfb1b360.png

个人愿景

身为拉勾大数据一期的学员,非常感谢拉勾,感谢课程的全面,让我能够收获到了很多,老师一直强调笔记的重要性,通过对课程的学习和老师提供的讲义,然后通过自己比较习惯的方式记录下来,加深了知识的记忆,我会坚持下去,还有3个月左右的课程,继续加油,最后,也祝愿大家都能找到一份自己满意的工作,与君共勉~

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值