1 两种模式区别
Spark Application提交运行时部署模式Deploy Mode,表示的是Driver Program运行的地方,要么是提交应用的Client:client,要么是集群中从节点(Standalone:Worker,YARN:NodeManager):cluster。
这里我做个简单总结下面的话:client模式就是driver运行在本地一般不用各种问题,cluster模式driver运行在Yarn集群中,性能较好,Cluster和Client模式最最本质的区别是:Driver程序运行在哪里。
--deploy-mode DEPLOY_MODE Whether to launch the driver program locally ("client") or on one of the worker machines inside the cluster ("cluster")(Default: client).
默认值为client,当时在实际项目中,尤其在生产环境,使用cluster部署模式提交应用运行。
1.1 client 模式
以Spark Application运行到Standalone集群上为例,前面提交运行圆周率PI或者词频统计
WordCount程序时,默认DeployMode为Client,表示应用Driver Program运行在提交应用Client
主机上(启动JVM Process进程),示意图如下:
假设运行圆周率PI程序,采用client模式,命令如下:
SPARK_HOME=/export/server/spark ${SPARK_HOME}/bin/spark-submit \ --master spark://node1.oldlu.cn:7077,node2.oldlu.cn:7077 \ --deploy-mode client \ --driver-memory 512m \ --executor-memory 512m \ --num-executors 1 \ --total-executor-cores 2 \ --class org.apache.spark.examples.SparkPi \ ${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \ 10
1.2 cluster 模式
如果采用cluster模式运行应用,应用Driver Program运行在集群从节点Worker某台机器上,示
意图如下:
假设运行圆周率PI程序,采用cluster模式,命令如下:
SPARK_HOME=/export/server/spark ${SPARK_HOME}/bin/spark-submit \ --master spark://node1.oldlu.cn:7077,node2.oldlu.cn:7077 \ --deploy-mode cluster \ --supervise \ --driver-memory 512m \ --executor-memory 512m \ --num-executors 1 \ --total-executor-cores 2 \ --class org.apache.spark.examples.SparkPi \ ${SPARK_HOME}/examples/jars/spark-examples_2.11-2.4.5.jar \ 10
1.3 两者比较
Cluster和Client模式最最本质的区别是:Driver程序运行在哪里。
cluster模式:生产环境中使用该模式
Driver程序在YARN集群中
应用的运行结果不能在客户端显示
client模式:学习测试时使用,开发不用,了解即可
Driver运行在Client上的SparkSubmit进程中
应用程序运行结果会在客户端显示
2 Spark on YARN
当应用提交运行到Hadoop YARN上时,包含两个部分:应用管理者AppMaster和于运行应用
进程Process(如MapReduce程序MapTask和ReduceTask任务),如下图所示:
Spark Application提交运行在集群上时,应用架构有两部分组成:Driver Program(资源申请
和调度Job执行)和Executors(运行Job中Task任务和缓存数据),都是JVM Process进程:
所以Spark Application运行在YARN上时,采用不同DeployMode时架构不一样,企业实际生
产环境还是以cluster模式为主,client模式用于开发测试,两者的区别面试中常问。
2.1 YARN Client 模式
在YARN Client模式下,Driver在任务提交的本地机器上运行,示意图如下:
具体流程步骤如下:
1)、Driver在任务提交的本地机器上运行,Driver启动后会和ResourceManager通讯申请启动ApplicationMaster;
2)、随后ResourceManager分配Container,在合适的NodeManager上启动ApplicationMaster,
此时的ApplicationMaster的功能相当于一个ExecutorLaucher,只负责向ResourceManager申
请Executor内存;
- 3)、ResourceManager接到ApplicationMaster的资源申请后会分配Container,然后
ApplicationMaster在资源分配指定的NodeManager上启动Executor进程;
4)、Executor进程启动后会向Driver反向注册,Executor全部注册完成后Driver开始执行main
函数;
5)、之后执行到Action算子时,触发一个Job,并根据宽依赖开始划分Stage,每个Stage生成
对应的TaskSet,之后将Task分发到各个Executor上执行。
以运行词频统计WordCount程序为例,提交命令如下:
/export/server/spark/bin/spark-submit \ --master yarn \ --deploy-mode client \ --driver-memory 512m \ --executor-memory 512m \ --executor-cores 1 \ --num-executors 2 \ --queue default \ --class cn.oldlu.spark.submit.SparkSubmit \ hdfs://node1.oldlu.cn:8020/spark/apps/spark-chapter01_2.11-1.0.0.jar \ /datas/wordcount.data /datas/swcy-client
2.2 YARN Cluster 模式
在YARN Cluster模式下,Driver运行在NodeManager Contanier中,此时Driver与AppMaster
合为一体,示意图如下:
具体流程步骤如下:
1)、任务提交后会和ResourceManager通讯申请启动ApplicationMaster;
2)、随后ResourceManager分配Container,在合适的NodeManager上启动ApplicationMaster,
此时的ApplicationMaster就是Driver;
3)、Driver启动后向ResourceManager申请Executor内存,ResourceManager接到
ApplicationMaster的资源申请后会分配Container,然后在合适的NodeManager上启动
Executor进程;
4)、Executor进程启动后会向Driver反向注册;
5)、Executor全部注册完成后Driver开始执行main函数,之后执行到Action算子时,触发一个
job,并根据宽依赖开始划分stage,每个stage生成对应的taskSet,之后将task分发到各个
Executor上执行;
以运行词频统计WordCount程序为例,提交命令如下:
/export/server/spark/bin/spark-submit \ --master yarn \ --deploy-mode cluster \ --driver-memory 512m \ --executor-memory 512m \ --executor-cores 1 \ --num-executors 2 \ --queue default \ --class cn.oldlu.spark.submit.SparkSubmit \ hdfs://node1.oldlu.cn:8020/spark/apps/spark-chapter01_2.11-1.0.0.jar \ /datas/wordcount.data /datas/swcy-cluster
3 MAIN函数代码执行
Spark Application应用程序运行时,无论client还是cluster部署模式DeployMode,当Driver
Program和Executors启动完成以后,就要开始执行应用程序中MAIN函数的代码,以词频统计
WordCount程序为例剖析讲解。
第一、构建SparkContex对象和关闭SparkContext资源,都是在Driver Program中执行,上图中
①和③都是,如下图所示:
第二、上图中②的加载数据【A】、处理数据【B】和输出数据【C】代码,都在Executors上执
行,从WEB UI监控页面可以看到此Job(RDD#action触发一个Job)对应DAG图,如下所示:
将结果数据resultRDD调用saveAsTextFile方法,保存数据到外部存储系统中,代码在Executor
中执行的。但是如果resultRDD调用take、collect或count方法时,获取到最终结果数据返回给Driver,
代码如下:
运行应用程序时,将数组resultArray数据打印到标准输出,Driver Program端日志打印结果:
综上所述Spark Application中Job执行有两个主要点:
1)、RDD输出函数分类两类
第一类:返回值给Driver Progam,比如count、first、take、collect等
第二类:没有返回值,比如直接打印结果、保存至外部存储系统(HDFS文件)等
2)、在Job中从读取数据封装为RDD和一切RDD调用方法都是在Executor中执行,其他代码都
是在Driver Program中执行
SparkContext创建与关闭、其他变量创建等在Driver Program中执行
RDD调用函数都是在Executors中执行
4 再续 Spark 应用
当Spark Application运行在集群上时,主要有四个部分组成,如下示意图:
1)、Driver:是一个JVM Process 进程,编写的Spark应用程序就运行在Driver上,由Driver进
程执行;
2)、Master(ResourceManager):是一个JVM Process 进程,主要负责资源的调度和分配,并
进行集群的监控等职责;
3)、Worker(NodeManager):是一个JVM Process 进程,一个Worker运行在集群中的一台服
务器上,主要负责两个职责,一个是用自己的内存存储RDD的某个或某些partition;另一个是
启动其他进程和线程(Executor),对RDD上的partition进行并行的处理和计算。
4)、Executor:是一个JVM Process 进程,一个Worker(NodeManager)上可以运行多个Executor,
Executor通过启动多个线程(task)来执行对RDD的partition进行并行计算,也就是执行我们
对RDD定义的例如map、flatMap、reduce等算子操作。
Spark支持多种集群管理器(Cluster Manager),取决于传递给SparkContext的MASTER环境变量的
值:local、spark、yarn,区别如下: