Spark调优(二)-----合理配置Spark集群的Executor,Core,Partition

概述

合理配置Executor,Core,Partition会大大提高集群的计算效率。
举个例子:100道计算题,如果一个人计算可能需要100min,但如果平均分配给10个人计算,每人算10道题,然后再汇总给一个人提交,那只需要10min就可以完成。
为了帮助大家更全面的理解底层原理和一些基本概念,先介绍Spark架构与Spark调度模块,调优在文章最末

目录
概述
Spark架构
Spark调度模块
实战与调优

Spark架构

为了帮助大家更全面的理解底层原理,先贴一张集群模式下的Spark程序运行架构图
在这里插入图片描述

1.Driver Program

用户编写的Spark程序称为Driver Program。每个Driver程序包含一个代表集群环境的SparkContext对象,程序的执行从Driver程序开始,所有操作执行结束后回到Driver程序中,在Driver程序中结束。如果你是用spark shell,那么当你启动 Spark shell的时候,系统后台自启了一个 Spark 驱动器程序,就是在Spark shell 中预加载的一个叫作 sc 的 SparkContext 对象。如果驱动器程序终止,那么Spark 应用也就结束了。

2.SparkContext对象

每个Driver Program里都有一个SparkContext对象,职责如下:
1)SparkContext对象联系 cluster manager(集群管理器),让 cluster manager 为Worker Node分配CPU、内存等资源。此外, cluster manager会在 Worker Node 上启动一个执行器(专属于本驱动程序)。
2)和Executor进程交互,负责任务的调度分配。

3.cluster manager 集群管理器

它对应的是Master进程。集群管理器负责集群的资源调度,比如为Worker Node分配CPU、内存等资源。并实时监控Worker的资源使用情况。一个Worker Node默认情况下分配一个Executor(进程)。

从图中可以看到sc和Executor之间画了一根线条,这表明:程序运行时,sc是直接与Executor进行交互的。
所以,cluster manager 只是负责资源的管理调度,而任务的分配和结果处理它不管。

4.Worker Node

Worker节点。集群上的计算节点,对应一台物理机器。

5.Worker进程

它对应Worder进程,用于和Master进程交互,向Master注册和汇报自身节点的资源使用情况,并管理和启动Executor进程。

6.Executor

负责运行Task计算任务,并将计算结果回传到Driver中。

7.Task

在执行器上执行的最小单元。比如RDD Transformation操作时对RDD内每个分区的计算都会对应一个Task。

Spark调度模块

之前我们提到:Driver 的sc负责和Executor交互,完成任务的分配和调度,在底层,任务调度模块主要包含两大部分:
1)DAGScheduler
2)TaskScheduler
它们负责将用户提交的计算任务按照DAG划分为不同的阶段并且将不同阶段的计算任务提交到集群进行最终的计算。整个过程可以使用下图表示:在这里插入图片描述
RDD Objects可以理解为用户实际代码中创建的RDD,这些代码逻辑上组成了一个DAG。

DAGScheduler主要负责分析依赖关系,然后将DAG划分为不同的Stage(阶段),其中每个Stage由可以并发执行的一组Task构成,这些Task的执行逻辑完全相同,只是作用于不同的数据。

在DAGScheduler将这组Task划分完成后,会将这组Task提交到TaskScheduler。TaskScheduler通过Cluster Manager 申请计算资源,比如在集群中的某个Worker Node上启动专属的Executor,并分配CPU、内存等资源。接下来,就是在Executor中运行Task任务,如果缓存中没有计算结果,那么就需要开始计算,同时,计算的结果会回传到Driver或者保存在本地。

Scheduler的实现与概述在这里插入图片描述

任务调度模块涉及的最重要的三个类是:
1)org.apache.spark.scheduler.DAGScheduler 前面提到的DAGScheduler的实现。
将一个DAG划分为一个一个的Stage阶段(每个Stage是一组Task的集合)
然后把Task Set 交给TaskScheduler模块。
2)org.apache.spark.scheduler.TaskScheduler
它的作用是为创建它的SparkContext调度任务,即从DAGScheduler接收不同Stage的任务。向Cluster Manager 申请资源。然后Cluster Manager收到资源请求之后,在Worker为其启动进程
3)org.apache.spark.scheduler.SchedulerBackend
是一个trait,作用是分配当前可用的资源,具体就是向当前等待分配计算资源的Task分配计算资源(即Executor),并且在分配的Executor上启动Task,完成计算的调度过程。
4)AKKA是一个网络通信框架,类似于Netty,此框架在Spark1.8之后已全部替换成Netty

任务调度流程图
在这里插入图片描述

实战与调优

集群环境: 3台物理服务器,每台2个CPU,每个CPU有22核

执行命令: spark-submit --master yarn --deploy-mode client --class com.huawei.bigdata.spark.examples.testhe --conf spark.kryoserializer.buffer.max=256m --conf spark.kryoserializer.buffer=64m --conf spark.executor.memory=4g –conf spark.executor.cores=20 --conf spark.cores.max=180 –num-executors 9 --conf spark.default.parallelism=12 --deploy-mode client --keytab /opt/wzl/superuser.keytab --principal cl_test --files /opt/hadoopclient/Spark2x/spark/conf/user.keytab --jars /opt/hadoopclient/Spark2x/spark/jars/jts-1.13.jar,/opt/hadoopclient/Spark2x/spark/jars/fastjson-1.2.4.jar,/opt/hadoopclient/Spark2x/spark/jars/streamingClient010/kafka-clients-0.11.0.1.jar,/opt/hadoopclient/Spark2x/spark/jars/streamingClient010/kafka_2.11-0.11.0.1.jar,/opt/hadoopclient/Spark2x/spark/jars/streamingClient010/spark-streaming-kafka-0-10_2.11-2.1.0.jar /opt/hadoopclient/Spark2x/spark/conf/Spark02.jar /tmp/test1 10.12.7.101:21007 test04 1200

标记处,我们指定Core20核(此处指定的核数是Spark的虚拟核数),指定Executors为9,也就是说我们现在并行执行的任务数Task=20×9=180个。相当于有180个线程在并行计算,而我们在代码中使用了repartition,将数据分区为180个,这样就可以保证每个线程都有数据可以用来计算,没有空闲的线程。

问:为什么指定Executors=9?
这是根据我们程序的计算逻辑找到的一个平衡点。
Executors的两种指定方式:
Fat: Nodes(节点数)× Cores(核数)
Tiny:Nodes(节点数)
例如:我们的集群是3个节点,每个节点22核,所以我们可以指定3×22=66个Executors,我们也可以指定3个Executors,同时,我们可以在3与66之间找到一个平衡点,因为指定的Executors越多,每个Executors分得的内存就越少,这里会涉及到GC与JVM,就不再多展开了,如果是Yarn模式,还会有预留的内存。

最后贴上两篇国外的文章,有更详细的介绍
链接: link1
链接: link2-part1
链接: link2-part2

猜你喜欢

转载自blog.csdn.net/weixin_44336726/article/details/102799819