spark任务shell运行_了解Spark 应用的一生

c114b85501b43aff2383fe65dc7fcedf.png

Spark从被创造至今已经成为了大数据计算引擎中不可或缺的一环,虽然Spark非常的优秀但相比于其他的开源框架依然有着比较高的学习门槛,希望能够通过一种有结构性的,简单直接的方式,为Spark的初学者入门。

核心概念讲解

Spark 应用的架构

Driver

Driver 是整体Spark Application的架构中最重要的一个进程。为了便于理解,我们可以将Driver理解为是一个建筑工地的包工头,他了解整个项目的实施步骤与实施内容。它主要负责分派任务,监督任务的进程,同时还需要时刻关心项目需要的建筑材料是否充分。

Executor

Executor 是除了Drvier以外负责执行任务的进程。这些任务都由Driver来指定。Executor可以被理解为包工头下面的工人,他们不需要太多思考,而是专注于完成指定的任务。他们只需要接受任务,执行,并将执行后的状态与结果返回即可。

Cluster Manager

Cluster Manager的概念比以上的概念稍微较难理解一些,Cluster Manager搭建了Spark Application与具体的物理机器的桥梁。如果将Spark Application理解为一个施工项目的话,那么Cluster Mangager可以理解为是一个建筑材料管理者。一个施工项目的完成需要提供足够的建材支持执行,而当需要这些资源的时候,便需要与Cluster Manager交流。当然这只是为了便于理解而做的类比。真正的Cluster Manager中也会有自己的结构,也是一个Master/Workor的结构。这样的结构是为了更好的管理分布式的集群的物理机器。我们可以通过下图对Cluster Mangager有一个了解。现在Spark支持Standalone, Mesos, Yarn 三种方式,K8s会在Spark3之后支持。

1f491a6183d754cdf17b8acb2a55a15e.png

Spark 执行模式

在理解了一个Spark Application里面的组成部分之后,我们来看看Spark Application能够执行的模式

Cluster Mode

Cluster Mode是Spark Application最常用的模式。在生产环境除非特殊原因都会采用Cluster的模式来执行。在Cluster mode下,用户提交一个Jar,pyton script或者R sciprt给Cluster Manager。之后Cluster Manager在某一个Workor节点上启动Driver的进程。在Cluster Mode下,Cluster manager负责维持所有Spark应用进程。下图便解释了Cluster mode执行时的状态。Cluster Manager选取一个Workor节点跑Driver,之后再分配其他Worker跑其余的Executor。

90ff7a66bab47a9ff9b505ddceecfa30.png

Client Mode

Client Mode与Cluster Mode基本一致除了Driver进程并非由Cluster Manager来管理,而是继续跑在提交任务的机器上。这也就意味着,Driver进程将由提交任务的客户端来维持状态。Cluster Manager只是负责维持Executor的状态。这些维持Driver的节点,也被叫做Edge Node或者gateway Machines。下图便解释了Client Mode的运行机制。

de6132226ca310345f27728543fdf46c.png

Local Mode

Local Mode是一种为了测试与开发Spark应用而存在的模式。它与前两种截然不同。Local模式在一台物理机器上运行,同时Executor与Driver也从进程变为线程。在生产环境中几乎没有不会使用local 模式。

小结

我们不妨思考一下,Spark为什么会创建出三种不同的运行模式。什么时候又会使用什么样的模式。Cluster的模式适用于大部分应用场景,可以将它理解为一种离线提交任务的方式。Client模式非常适合shell, notebook这一类需要一直有一个主线程维持着的应用。而Local模式基本只适合测试的场景。

Spark 应用的执行过程

了解了Spark系统的组成部分,我们来看一个在Cluster Mode下跑的Spark Application的过程。

第一步, 任务请求

我们一般通过Spark-submit来提交一个Spark 应用,提交的时候需要提供已经编译好的Jar包或者是python script,等这取决于不同的语言而不同。

c9d417405cfd255b5879f3346b765440.png

通过上图可以看到,执行这一步任务的进程还是在你自己本地的机器上,它需要负责给Cluster Manager发送请求,表明需要的资源大小。我们现在假设我们有足够的资源,因此Cluster Manager接受了我们的请求,并寻找了一个Worker Node将Driver跑起来。如果一切顺利,那么此本地进程就会结束退出。

以下是一个任务提交的示例

./bin/spark-submit  
--class <main-class>  
--master <master-url>  
--deploy-mode cluster  
--conf <key>=<value>  
... # other options 
<application-jar>  
[application-arguments]

第二步,任务启动

当Driver进程开始之后,Driver会拥有一个SparkSession的对象。SparkSession定义了运行这个Spark Application所需要的环境信息。这包含了用多少资源,与Cluster Manager的沟通方式等。这些大部分都是在Spark-submit的时候可以进行设置的内容。

831d0901a0b310aa3eff30b135d1589f.png

在这个过程中,Driver通过SparkSession这个对象,向Cluster Manager请求资源并建立起这个任务需要的集群,这样一个可以用于执行Spark Application的集群便准备好了。这里需要注意,当Cluster Manager在分配了资源之后,它会将这些信息给到Driver,之后Driver便可以直接与这些Executor交流。之后除非有新的资源请求,不然就不用再找Cluster Manager了。

第三步,任务执行

执行阶段我们之后会将其中涉及的概念与过程详细展开。现在我们只需要知道这时候Driver已经掌握了足够的信息来执行应用了。所以会开始分配executor到不同的Worker node上去。

b5b9f22fcb1f0e261f6e9e385d63a466.png

我们需要注意这时候整体的控制权都是Driver手里,这个时候Cluster Manager只需要维持着Driver进程的状态即可,Cluster Manager并不感知任务的具体内容。

任务完成

Driver的退出便标志着应用的完成,Driver退出时的状态也会同时传给Cluster Manager。这时候Cluster Manager会负责将之前分配的资源回收,并将Driver返回的状态返回。

1a9e155b6b03fcb98f4f7524472cbc43.png

Spark 应用内部的过程

接下来我们仔细看看Spark Application在执行的阶段内部都在发生着什么。为了能够清楚的讲清楚其中的过程,我们需要先引入Spark Application中的一些新的概念。

Spark Session

在Spark应用的一开始便是获取一个Spark Session.如果是使用Spark-Shell,或者Zepplion等工具,你可能没有意识到这个Session已经在你启动Shell的时候获得了。由于Spark版本的不同,初始化Spark Session的方式也经历了很多的变化,由于我们旨在讲明白Spark Application的内部运行流程,就不在Spark Session的方面进行过多的描述。我们只需要了解我们需要获取SparkSession,之后才能获得不同的Context对象来进行Spark Application的开发。我们可以调用SparkSQL的服务,也可以调用底层的RDD的服务。这些都由不同的业务需求而确定。

Logical Instructions

无论你使用什么语言进行Spark Application的开发,最终都会转化为一个Logical Instruction的计划,然后再变为一个物理执行计划。如果你想要更加直观的了解执行计划,你可以打开Spark的UI。这时候我们便需要继续介绍一下Spark Job的组成了。

在介绍Spark的Job组成之前,我们需要再引入两个概念,一个是transformation,一个是shuffle。这对应着在Spark中两种不同的数据变换逻辑。如果对Map-Reduce有了解的话那么就不难理解,Transformation可以理解为Mapper能够完成的逻辑,而Shuffle就是需要Reducer才能完成的逻辑。我们之后会将为什么这两类运算对于Spark的计划来说非常的重要。

Spark Job

Spark Job在Spark Application中对应的就是一个Action的操作。这时又需要引入Spark的Lazy Evaluation的机制。Spark只有在需要获取结果的时候才会进行运算,在这之前只会保留执行的计划而不会调用任何计算的逻辑。

一个Job是有很多的Stage组成的,而一个Stage会包含若干个Task。

Spark Stage

一个Stage可以理解为是一组能够被并行执行的Task的集合,一个Shuffle的操作对应一个Stage。Spark之所以执行的速度比Map-reduce要优秀,就是因为它能够做良好的优化,能够合理的将一个计算任务进行整合。举个例子如果你的操作都是select, filter等,那么他们会被整合在一个Stage当中去完成。而整合的极限便是如果你需要做不同的Shuffle的操作,比如Sort, Grouping。那么Spark便会分开不同的Stage来执行。

Spark Tasks

一个Task就是Spark执行中的最小单元,它跑在一台机器上。有多少的Task需要被执行,是有多少的partition来决定的。这里不做过多的赘述。我们只要理解Task是最小的执行单元便可以。

Spark为什么快如闪电

1. Pipelining

Pipeling是Spark Application中最具特色的部分,大部分select, filter的操作都会通过pipeling的方式放在一个Stage中执行。在这样的执行中会尽量的使用内存而非存储,也正是因为这样的优化使得Spark在执行很多相同的任务中有着更好的表现。

2. Shuffle Persistence

当Spark需要做一个Shuffle的作业时,Spark会先将输入落盘。这样的选择不仅是为了以后做shuffle时的方便,同时它还带来了一个额外的好处,便是因为shuffle之前的内容已经落盘,所以如果重新执行这个任务的话,已经落盘的部分会自动的跳过。

总结

我们分别讲解了Spark集群的架构,一个Spark Application如何利用分布式的架构执行,以及在执行的过程中Spark是如何处理内部的应用的。略显粗浅,但基本涵盖了Spark 应用的方方面面。可以算是Spark应用理解的启蒙读物吧。

Reference

[Spark 权威指南]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值