继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Spark调优基础与经验

损失函数
关注TA
已关注
手记 70
粉丝 1533
获赞 2735

一、当一个spark任务submit到yarn集群需要经过有几步?

《spark必知必会的基本概念》解释了yarn集群的运行过程,理解了Resource Manager、Node Manager、Application master这些基本概念,并且它们之间是如何通信的。那么当一个spark任务submit到yarn集群需要经过有几步?

1.1 在client使用spark-submit提交一个spark任务后

图片描述

  1. 首先,每个任务会对应启动一个Driver进程
  2. 然后,Driver进程为spark任务申请资源:向集群管理器Resource Manager申请运行Spark作业需要使用的资源,主要的资源是Executor进程,Executor进程数量以及所需的CPU core可以通过spark任务设置的资源参数来指定;
  3. 其次,Driver进程会将Spark任务代码分拆为多个stage:资源申请完毕后,开始调度与执行任务代码,第一步就是将job拆分多个stage;
  4. 然后,Driver进程为每个stage创建一批task
  5. 最后,将这些task分配到各个Executor进程中执行

1.2 过程很简单,有几个问题值得思考:

  • Driver进程在哪里启动的?
  • Executor的内存分布?
  • stage如何拆分的?(第二节介绍)

1.2.1 Driver进程的启动方式根据任务部署模式的不同而不同:

  • local(本地模式):Driver进程直接运行在本地
  • yarn-client:Driver运行在本地
  • yarn-cluster:Driver运行在集群中(NodeManager)

1.2.2 Executor的内存分布:

  • 执行task所需内存,默认20%
  • shuffle所需内存,默认20%
  • RDD cache或persist持久化所需内存,默认60%

二、spark调优的基本概念

我们在client提交一个spark任务后,可以在spark web ui看到,当我们运行scala代码的时候,后台都发生了什么,通过分析ui的数据可以指导代码性能优化。一段代码至少由一个job来执行(在Jobs页面可查看,如下图),每个job可能由一个或多个stage完成(在Stages页面可查看,或点击job里的Description链接查看),而每个state由多个task线程完成(在Executors页面查看,或点击Stages里的Description链接查看)。通过查看顺序也可以看到job-stage-task的层级关系。

图片描述
图片描述

那到底什么是job stage task?

2.1 job

A job (aka action job or active job) is a top-level work item (computation) submitted to DAGScheduler to compute the result of an action (or for Adaptive Query Planning / Adaptive Scheduling).

job指的是在提交的spark任务中一个action,可以在spark ui的Jobs中可以看到Active Jobs为你的action的名称。

图片描述

2.2 stage

A stage is a physical unit of execution. It is a step in a physical execution plan.

Spark actions are executed through a set of stages, separated by distributed “shuffle” operations.

图片描述

一个job会被拆分为一个或多个stage来执行,每个stage执行一部分代码片段,各个stage会按照执行顺序来执行,而job按照什么规则来划分stage呢?

spark根据shuffle类算子(如join)来进行stage的划分,即在shuffle类算子之前的代码为一个stage,在该shuffle类算子之后的代码则会下一个stage,那么每个stage的执行不需要对整个数据集进行shuffle即可完成。什么是shuffle,后面会讲到。

2.3 task

A stage is a set of parallel tasks — one task per partition (of an RDD that computes partial results of a function executed as part of a Spark job).

Task (aka command) is the smallest individual unit of execution that is launched to compute a RDD partition.

图片描述

一个stage由一批task线程来执行,task是spark最小的计算单元,每个task执行相同的逻辑计算,但使用不同分区的数据,一个分区一个task

2.4 shuffle过程

一个shuffle过程是:一个stage执行完后,下一个stage开始执行的每个task会从上一个stage执行的task所在的节点,通过IO获取task需要处理的所有key,然后每个task对相同的key进行算子操作。这个过程被称为shuffle过程。

三、常见参数调优经验

第一节“submit的背后步骤”中我们提到了Driver进程会为spark任务申请资源,合理使用集群资源,是优化spark任务执行性能最基本最直接的方式。资源申请少了,可能导致任务执行非常缓慢甚至出现OOM,无法充分利用集群资源;资源申请多了,当前队列可能无法分配充分资源,同时也影响别的同学任务的执行。

如果你和别人共享一个队列的资源,可以根据集群 ui 的scheduler上目前资源使用情况(比如最大/小的资源数,当前资源数,最大运行任务数,当前运行任务数等)来设置要申请多少资源,申请多少资源可以通过各种常用资源参数来调节。

资源参数 Environment Properties 参数含义 默认值 参数意义 调优建议
–num-executors spark.executor.instances spark任务在集群中使用多少个executor 2个 不设置集群会使用默认的少量的Executor进程来执行spark任务,速度缓慢 必须,根据spark任务和集群资源队列现有情况设置,官方并没有建议,但美团技术团队的同学建议50-100
–executor-memory spark.executor.memory executor的内存大小 1G 对spark任务性能优劣起了决定性作用,常见的JVM OOM与之有关联 必须,num-executors * executor-memory=资源队列总内存*(1/3~1/2)
–executor-cores spark.executor.cores executor的cpu核数 1 与上一参数决定了一个Executor的资源,cpu核数表示了每个Executor可以并行执行多少个task 必须,num-executors * executor-cores=资源队列总CPU core数*(1/3~1/2)
无(在spark conf配置) spark.default.parallelism RDD默认的分区数,即每个stage默认的task数量 有shuffle类算子则取决于RDD最大分区数;无则取决于集群部署模式:Local(本地机器核数);Mesos fine grained(8);other(max(所有executor的cpu核数,2)) 不设置可能会直接影响spark任务的执行效率 必须,num-executors * executor-cores * (2~3)

markdown表格看不全,截图如下:
图片描述

打开App,阅读手记
1人推荐
发表评论
随时随地看视频慕课网APP