#博学谷IT学习技术支持#
1.环境搭建-Spark on YARN
将Spark Application提交运行到YARN集群上,至关重要,企业中大多数都是运行在YANR上,文档:http://spark.apache.org/docs/3.1.2/running-on-yarn.html#launching-spark-on-yarn。
spark on yarn 模式官方文档说明:
http://spark.apache.org/docs/latest/running-on-yarn.html
http://spark.apache.org/docs/latest/running-on-yarn.html#configuration
同时注意,如果我们的spark程序是运行在yarn上面的话,那么我们就不需要spark 的集群了,我们只需要找任意一台机器配置我们的spark的客户端提交任务到yarn集群上面去即可。
Yarn是一个成熟稳定且强大的资源管理和任务调度的大数据框架,在企业中市场占有率很高,意味着有很多公司都在用Yarn,将公司的资源交给Yarn做统一的管理!并支持对任务做多种模式的调度,如FIFO/Capacity/Fair等多种调度模式!
所以很多计算框架,都主动支持将计算任务放在Yarn上运行,如Spark/Flink
企业中也都是将Spark Application提交运行在YANR上。
1.1 SparkOnYarn本质
Spark On Yarn的本质?
将Spark任务的pyspark文件,经过Py4J转换,提交到Yarn的JVM中去运行
Spark On Yarn需要啥?
1.需要Yarn集群:已经安装了
2.需要提交工具:spark-submit命令--在spark/bin目录
3.需要被提交的PySpark代码:Spark任务的文件,如spark/examples/src/main/python/pi.py中有示例程序,或我们后续自己开发的Spark任务)
4.需要其他依赖jar:Yarn的JVM运行PySpark的代码经过Py4J转化为字节码,需要Spark的jar包支持!Spark安装目录中有jar包,在spark/jars/中
1.3 部署模式DeployMode
Spark Application提交运行时部署模式Deploy Mode,表示的是Driver Program运行的地方,要么是提交应用的Client:client,要么是集群中从节点(Standalone:Worker,YARN:NodeManager):cluster。
默认值为client,当时在实际项目中,尤其在生产环境,使用cluster部署模式提交应用运行。
两种模式区别
Cluster和Client模式最最本质的区别是:Driver程序运行在哪里。
client 模式
此种模式:
1)Driver 在本地运行
2)Executor 在集群的Worker节点上运行
以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.itcast.cn:7077,node2.itcast.cn:7077 \
--deploy-mode client \
--driver-memory 512m \
--executor-memory 512m \
--num-executors 1 \
--total-executor-cores 2 \
--conf "spark.pyspark.driver.python=/root/anaconda3/bin/python3" \
--conf "spark.pyspark.python=/root/anaconda3/bin/python3" \
${SPARK_HOME}/examples/src/main/python/pi.py \
10

cluster 模式
在cluster模式中,无论是Driver还是Executor都是运行在Worker节点上。
注意:
1)测试运行程序时,可以使用client和cluster部署模式
2)生产环境中,建议使用cluster部署模式,必须使用此种模式
如果采用cluster模式运行应用,应用Driver Program运行在集群从节点Worker某台机器上,示意图如下:

假设运行圆周率PI程序,采用cluster模式,命令如下:
SPARK_HOME=/export/server/spark
${SPARK_HOME}/bin/spark-submit \
--master spark://node1.itcast.cn:7077,node2.itcast.cn:7077 \
--deploy-mode cluster \
--driver-memory 512m \
--executor-memory 512m \
--num-executors 1 \
--total-executor-cores 2 \
--conf "spark.pyspark.driver.python=/root/anaconda3/bin/python3" \
--conf "spark.pyspark.python=/root/anaconda3/bin/python3" \
${SPARK_HOME}/examples/src/main/python/pi.py \
10
两者比较
Cluster和Client模式最最本质的区别是:Driver程序运行在哪里。
cluster模式:生产环境中使用该模式
Driver程序在YARN集群中
应用的运行结果不能在客户端client显示
client模式:学习测试时使用,开发不用,了解即可
Driver运行在Client上的SparkSubmit进程中
应用程序运行结果会在客户端显示
1.4 Spark On Yarn两种模式
当一个MR应用提交运行到Hadoop YARN上时
包含两个部分:应用管理者AppMaster和运行应用进程Process(如MapReduce程序MapTask和ReduceTask任务),如下图所示:

当一个Spark应用提交运行在集群上时,
应用架构有两部分组成:Driver Program(资源申请和调度Job执行)和Executors(运行Job中Task任务和缓存数据),都是JVM Process进程:

而Driver程序运行的位置可以通过--deploy-mode 来指定, 值可以是:
1.client:表示Driver运行在提交应用的Client上(默认)
2.cluster:表示Driver运行在集群中(Standalone:Worker,YARN:NodeManager)
client 模式
lDeployMode为Client,表示应用Driver Program运行在提交应用Client主机上,示意图如下:

l运行圆周率PI程序,采用client模式,命令如下:
SPARK_HOME=/export/server/spark
${SPARK_HOME}/bin/spark-submit \
--master yarn \
--deploy-mode client \
--driver-memory 512m \
--executor-memory 512m \
--executor-cores 1 \
--num-executors 2 \
--queue default \
--conf "spark.pyspark.driver.python=/root/anaconda3/bin/python3" \
--conf "spark.pyspark.python=/root/anaconda3/bin/python3" \
${SPARK_HOME}/examples/src/main/python/pi.py \
10

cluster 模式
lDeployMode为Cluster,表示应用Driver Program运行在集群从节点某台机器上,示意图如下:

l运行圆周率PI程序,采用cluster模式,命令如下:
${SPARK_HOME}/bin/spark-submit \
--master yarn \
--deploy-mode cluster \
--driver-memory 512m \
--executor-memory 512m \
--executor-cores 1 \
--num-executors 2 \
--queue default \
--conf "spark.pyspark.driver.python=/root/anaconda3/bin/python3" \
--conf "spark.pyspark.python=/root/anaconda3/bin/python3" \
${SPARK_HOME}/examples/src/main/python/pi.py \
10

l结果查看:http://node1:8088/cluster
l进入8088yarn应用目录

总结
Client模式和Cluster模式最最本质的区别是:Driver程序运行在哪里。
Client模式:学习测试时使用,开发不用,了解即可
1.Driver运行在Client上,和集群的通信成本高
2.Driver输出结果会在客户端显示
Cluster模式:生产环境中使用该模式
1.Driver程序在YARN集群中,和集群的通信成本低
2.Driver输出结果不能在客户端显示
3.该模式下Driver运行ApplicattionMaster这个节点上,由Yarn管理,如果出现问题,yarn会重启ApplicattionMaster(Driver)
扩展阅读:两种模式详细流程
在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上执行。

在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上执行;

2.Spark关键概念
2.1 扩展阅读: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等算子操作。
2.2 Spark-shell和Spark-submit
Spark支持多种集群管理器(Cluster Manager),取决于传递给SparkContext的MASTER环境变量的值:local、spark、yarn,区别如下:

3.PySpark角色分析
核心架构图

角色分析
(1)在Driver端,通过Py4j实现在Python中调用Java的方法,即将用户写的PySpark程序”映射”到JVM中,例如,用户在PySpark中实例化一个Python的SparkContext对象,最终会在JVM中实例化Scala的SparkContext对象;
(2)在Executor端,则不需要借助Py4j,因为Executor端运行的Task逻辑是由Driver发过来的,那是序列化后的字节码,虽然里面可能包含有用户定义的Python函数或Lambda表达式,Py4j并不能实现在Java里调用Python的方法,为了能在Executor端运行用户定义的Python函数或Lambda表达式,则需要为每个Task单独启一个Python进程,通过socket通信方式将Python函数或Lambda表达式发给Python进程执行。
相关组件组件:
master:主节点进程,在整个集群中,最多只有一个Master处于Active状态。在使用spark-shell等交互式运行或者使用官方提供的run-example实例时,Driver运行在Master节点中;若是使用spark-submit工具进行任务的提交或者IDEA等工具开发运行任务时,Driver是运行在本地客户端的。
worker:从节点进程,类似于yarn中的NodeManager,在整个集群中,可以有多个Worker(>0)。负责当前WorkerNode上的资源汇报、监督当前节点运行的Executor。并通过心跳机制来保持和Master的存活性连接。Executor受到Worker掌控,一个Worker启动Executor的个数受限于 机器中CPU核数。每个Worker节点存在一个多个CoarseGrainedExecutorBackend进程,每个进程包含一个Executor对象,该对象持有一个线程池,每个线程执行一个Task。
核心概念
(1)Application:指的是用户编写的Spark应用程序,包含了含有一个Driver功能的代码和分布在集群中多个节点上运行的Executor代码。
(2)Driver:运行Application的main函数并创建SparkContext,SparkContext的目的是为了准备Spark应用程序的运行环境。SparkContext负责资源的申请、任务分配和监控等。当Executor运行结束后,Driver负责关闭SparkContext;
(3)Job:一个Application可以产生多个Job,其中Job由Spark Action触发产生。每个Job包含多个Task组成的并行计算。
(4)Stage:每个Job会拆分为多个Task,作为一个TaskSet,称为Stage;Stage的划分和调度是由DAGScheduler负责的。Stage分为Result Stage和Shuffle Map Stage;
(5)Task:Application的运行基本单位,Executor上的工作单元。其调度和 管理由TaskScheduler负责。
(6)RDD:Spark基本计算单元,是Spark最核心的东西。表示已被分区、被序列化、不可变的、有容错机制的、能被并行操作的数据集合。
(7) DAGScheduler:根据Job构建基于Stage的DAG,划分Stage依据是RDD之间的依赖关系。
(8)TaskScheduler:将TaskSet提交给Worker运行,每个Worker运行了什么Task于此处分配。同时还负责监控、汇报任务运行情况等。
4.PySpark架构
PySpark宗旨是在不破坏Spark已有的运行时架构,在Spark架构外层包装一层Python API,借助Py4j实现Python和Java的交互,进而实现通过Python编写Spark应用程序,其运行时架构如下图所示。

核心架构图

其中白色部分是新增的Python进程,在Driver端,通过Py4j实现在Python中调用Java的方法,即将用户写的PySpark程序”映射”到JVM中,例如,用户在PySpark中实例化一个Python的SparkContext对象,最终会在JVM中实例化Scala的SparkContext对象;在Executor端,则不需要借助Py4j,因为Executor端运行的Task逻辑是由Driver发过来的,那是序列化后的字节码,虽然里面可能包含有用户定义的Python函数或Lambda表达式,Py4j并不能实现在Java里调用Python的方法,为了能在Executor端运行用户定义的Python函数或Lambda表达式,则需要为每个Task单独启一个Python进程,通过socket通信方式将Python函数或Lambda表达式发给Python进程执行。语言层面的交互总体流程如下图所示,实线表示方法调用,虚线表示结果返回。