从经典的WordCount来看SparkCore运行架构
术语:
相关术语 | 含义 |
---|---|
Application | 基于Spark进行构建的用户程序 。由集群中的一个driver program以及多个executors组成 |
Application jar | 包含用户的Spark应用程序的Jar包。在某些场景下,用户可能想创建“Uber jar”,它包含用户的应用程序和它的依赖。用户的Jar不应该包含Hadoop和Spark的类库。不过这些类库将会在运行时被加载。 |
Driver program | Driver program是一个进程,它运行应用程序application里面的main()函数,并在main函数里面创建SparkContext |
Cluster manager | 一个外部服务,用于获取集群资源(比如: standalone manager, Mesos, YARN ) |
Deploy mode | 区分驱动程序进程的运行位置。在“集群”模式下,框架在集群内部启动驱动程序。在“客户端”模式下,提交者在集群外部启动驱动程序,在本地local启动driver,就是你在哪里提交,在哪台机器上提交,就在哪台机器上运行这个driver program。 |
Worker node | 被发送给一个executor的工作单元。每个executor上面可以跑多个task。 |
Executor | 在worker node上启动应用程序的进程,这个进程可以运行多个任务并将数据保存在内存或磁盘存储中。每个Spark应用程序都有它自己的一组executors。 |
Task | 被发送给一个executor的工作单元。每个executor上面可以跑多个task。 |
Job | 由Spark action触发的由多个tasks组成的并行计算。当一个Spark action(如save, collect)被触发,一个包含很多个tasks的并行计算的job将会生成。你可以在driver’s logs看到这个术语。就是说只要Spark 程序触发了一个action,它就是一个job。 |
Stage | 每个job被切分成小的任务集,这些小的任务集叫做stages,并且他们之间相互依赖(类似于MapReduce中的map和reduce阶段)。你可以在driver’s logs看到这个术语。 |
几点重要说明:
1)Application: Driver program , executors on the cluster.
2) Driver program: 就是我们写代码中的main 方法, 以及SparkContext
3) Deploy mode:
cluster: Driver是跑在container;
client:Driver就运行在你提交机器的本地
4)Executor: (在yarn中就是运行在container上)
① 是一个进程 (ps -ef 能查看的)
② run tasks (运行多个任务)
③ keeps data in memory or disk storage across them (将数据保存在内存或磁盘存储中)
④ Each application has its own executors (每个Spark应用程序都有它自己的一组executors).
A:executor1 2 3
B:executor1 2 3
5)Task:
A unit of work that will be sent to one executor(被发送给一个executor的工作单元)
在RDD中 : partitions == task (一个partition对应于一个task)
6) Job:
action ==> job 一个action 对应于一个job
案例(运行在spark-shell中):
scala> val rdd = sc.parallelize(List("a","wc","b","a","word","wc")).map((_,1),2).reduceByKey(_+_).collect
rdd: Array[(String, Int)] = Array((a,2), (b,1), (word,1), (wc,2))
分析:
上述wc案例中 reduceByKey是一个action操作,可知就会产生一个job
上图可知:
spark-shell 是应用程序,一个application 可以有 1到n个job
上图可知:
该job 产生了2个stage,一个job产生了2个task (因为程序中设置了2个分区)
遇到一个action就会触发一个job,上面的collect是一个action算子;
遇到shuffle就会触发一个stage,上面的reduceByKey存在shuffle过程会触发stage。
可以看出,它总共有2个stage,2个stage分别有两个任务,总共4个任务。
小结:
一个application:1到n个job
一个job : 1到n个stage构成
一个stage: 1到n个task task与partition一一对应
组件
译官网:
1)Spark应用程序在集群上以独立的进程集合运行,由主程序(称作驱动程序)中的SparkContext对象来协调和组织。一个Spark应用程序包括一个driver和多个executors
2)
集群模式下,SparkContext 能够连接不同类型的cluster managers集群管理器,比如说Spark自己的standalone cluster manager, Mesos或者YARN,而这些cluster managers所扮演的角色是在各个应用程序application之间分配资源。一旦Spark连接上这些cluster managers,Spark就获得了分布在集群各个节点上的executors,这些executors其实是一系列的进程,这些进程负责执行我们的应用程序application中的计算并存储相关的数据。接着,SparkContext将我们的应用程序代码发送给executors,这些应用程序代码是由JAR或者Python文件所定义并且传给SparkContext。最后,SparkContext把tasks发送给executors去执行。
3) Driver program里面包含SparkContext,它为了能够在集群上去运行,能够把作业运行到集群上面,需要SparkContext需要通过Cluster manager去集群上申请资源,比如去了两个节点上面申请了两个executors。一旦连接上,拿到了资源,获得了分布在集群各个节点上的executors后,SparkContext就可以将我们的应用程序代码发送给executors。最后,SparkContext把tasks发送给executors去执行
Note:
- 每个Spark应用程序都有属于它自己本身的executor进程,这些进程在这个Spark应用程序的整个生命周期都一直存活着,并且以多线程的方式来执行内部的多个tasks。这样做的好处是使各个应用之间相互隔离,无论是在调度层面scheduling side还是在执行层面executor side都是相互隔离的,从调度层面来看,每个driver调度属于它自身的tasks,从执行层面上来看,属于不同applications的tasks运行在不同的JVM上,(假如现在有两个Spark应用程序,分别有多个executors,这些executors分布在各个节点之上,假如两个Spark应用程序的其中分别有一个executor,它俩是可以在同一个节点上运行的,而且互不影响) 。然而,这也意味着不同的Spark applications(就是SparkContext的实例)之间是不能共享各自所属的数据,除非,你把数据写到外部存储系统。还有一个方法可以不用写到外部存储系统,比如说Alluxio内存高速虚拟分布式存储系统。
- Spark并不关心底层的cluster manager。只要Spark可以获取得到executor进程,并且这些executor进程能够互相通信,那么这个Spark应用程序即使运行在 同样支持其他applications的cluster manager(比如Mesos/YARN)上面相对来说也是比较容易的。
就是说spark可以跑在好多个地方,但是它并不去关心你的底层,不管你是standalone 还是Mesos还是YARN,它的代码都是一样的
3)在driver program的整个生命周期中,它一直在监听并且接收来自其executors的连接。(可以查看spark.driver.port in the network config sectio)。因此,driver program必须跟各个worker nodes节点网络互通
4)由于driver是在集群上调度各个任务的,所以它应该靠近工作节点运行,最好是在同一局域网上运行。如果你想发送请求给远端的集群,最好向驱动程序打开RPC并让它从附近提交操作,而不是远离工作节点运行Driver。
小结:
Spark应用程序是一组独立的进程,这些进程由一个driver program进程和多个executors进程组成。
driver :运行在Spark应用程序中的main方法,和Sparkcontext进程
Worker node:就是在它上面可以跑executor进程,对于Yarn来说,就是NM上面运行container
executor:它是一个进程,这个进程可以运行多个任务并将数据保存在内存或磁盘存储中
job,stage,task:就是当一个Spark应用程序遇到一个action的时候,就会创建一个job,job里面会有很多个stage,一个stage有多个task,task是进行计算的最小单元,task将会被发送到executor上面去执行。