Spark作业不知道该如何分配资源怎么办?

标签: dev | 发表时间:2022-01-12 00:00 | 作者:
出处:http://itindex.net/relian

前几天有好几个朋友问我关于spark作业分配资源的问题:即在提交作业的时候,不知道该分配多少资源比较好?我的回答是 靠经验,仔细想想靠经验这等于不是没说吗,总有一些方法论或者思路的吧。所以就有了这篇文章,下笔的时候着实是不知道该怎么写,所以在网上搜索了一下,看看大佬们是怎么回答的。赶巧了不是,还真发现3年前就有人问过这个问题。

看了下评论,我感觉我能看懂,但不知道朋友们是否能看懂,所以我想还是要再详细啰嗦一下吧

 

首先呢,spark官网给我们提供了一些硬件层面的建议,先上链接https://spark.apache.org/docs/latest/hardware-provisioning.html。


但是这个文章并没有很细粒度介绍应用级别该如何分配资源。不过涉及到的几个方向可以参考一下,比如 内存,CPU


首先来复习一下spark涉及到这两块部分参数如下:

--num-executors/(SparkSQL中是spark.executor.instances 参数)

该参数代表了作业使用的总共executor个数

--driver-memory/(SparkSQL配置的是spark.driver.memory参数)

该参数代表了Driver端所消耗的内存,通常Driver端不会消耗太多资源,所以不需要给太多资源。

--executor-memory(SparkSQL配置的是spark.executor.memory参数)

该参数代表了每个executor所占用的内存

--executor-cores/(SparkSQL配置的是spark.executor.cores参数)

该参数代表了一个executor中能够并行执行的task数(注意并行和并发的区别!)


通常一个Spark作业所消耗的总内存数>=(spark.executor.instances)*(spark.exector.memory);

所占用的CPU个数>=(spark.executor.instances)*(spark.exector.cores)。

这里之所以要用大于,是因为AppMaster也要占用资源的!扯到AppMaster,那需要再复习一下Yarn部分的两个参数:

yarn.nodemanager.resource.memory-mb

该参数表示的是nm可供Yarn使用最大可用内存

yarn.nodemanager.resource.cpu-vcores

该参数表示的是nm可供yarn使用的最大虚拟cpu数量


一般在实际生产环境中,yarn可分配的总资源肯定是已经分配好了的。甚至是会有单独的spark作业队列(这里也要看yarn的调度模式,是fair,还是fifo,还是capacity)。


我们这里先举个例子来说明下:假设我们有一个裸集群,共有6个节点,每个节点都是16c 64g的配置(真实情况下每个节点的配置可能是参差不齐的)。


但是我们不可能把所有的资源全分配到yarn上,还是要留一部分作为系统运转的,那么每个节点留1C 1G 好了,采取极限的方式。最后每个节点可供yarn分配的资源如下:

yarn.nodemanager.resource.memory-mb=63g

yarn.nodemanager.resource.cpu-vcores=15

那么总资源就是all_memory=63*6=378g;all_cpu=6*15=90c

我们假设每个Executor并行度为5,那么就需要90/5=18个executor,但是需要留一个给AppMaster,所以--num-exectors=17;刚才算下来总共需要18个Executor,一共6个节点,平均每个节点是启动3个exector,一个节点是63g,那么每个executor可占用内存就是21g,请注意哦:每个executor并不是把21g全部给作业用,还要留一部分资源用来存储栈,buffer之类的开销以此来保证稳定性,也就是常说的堆外内存,通过spark.executor.memoryOverhead参数来设置这块的开销,其值=max(384mb,0.1*executorMemory)。因此这部分堆外内存=max(384mb,0.1*21)~=2g。那么堆内内存=21-2=19g。


这里用表格来汇总一下:

也就是说在提交作业的时候,其参数配置值不能大于以下值(这里的例子是假设把资源全给你的任务去用!):

--executor-cores / spark.executor.cores = 5   
--executor-memory / spark.executor.memory = 19
--num-executors / spark.executor.instances = 17

节点数

内存/每节点

CPU/每节点

Yarn可分配最大内存数

Yarn可分配最大CPU

假设每个executor并行度数

总executor数

实际干活的executor数

每个节点可启动的executor数

每个executor占用的内存

堆外内存

实际干活所用到的内存

6

64g

16C

63g*6=378g

15C*6=90C

5

90C/5=18

18-1=17

18/6=3

63g/3=21g

max(384mb,0.1*21g)=2g

21g-2g=19g






9

90c/9=10

10-1=9

10/6~=2

63g/~=2~=37g

max(384mb,0.1*37g)=3g

37g-3=34g

可能有朋友会困惑,为什仫每个executor并行度设置为5,当然也可以调大。如果调大每个executor的并行度,也相当于是提高了并行能力,这样的话就减少了task来回轮询的次数,比如你有100个task,每个executor执行20个task,那么要轮询5次;如果每个executor设置50个task,那么要轮询2次;这样一来就会增大每个executor所持有的内存。


其实可以按照前面论坛里提到的一种评估方式就是按照task数量来倒推,官方建议一个cpu core是处理2~3个task。


那么假设有100个task,最多需要50c,还是按照上面的例子,这个时候就要看你是采取每个节点均摊的方式呢,还是某几个节点集中处理。采取何种方式还要结合你实际处理的数据量和计算复杂逻辑(因为这里还要思考网络消耗和本地化计算,每个节点的负载情况等等因素),当然通常情况下是采取均摊的方式,那么每个节点大概会使用8c。那么每个节点启动几个executor呢?是启动一个executor,还是2个executor,每个executor,每个executor大概占用多大内存呢?这个时候就要看你的代码逻辑是计算多一些还是缓存多一些。这里就涉及到内存模型的东西了,不知道内存模型的朋友再复习一下我原来写的文章: Tungsten On Spark-内存模型设计


尽管以上资源分配都已经评估好了,但并不代表后续不需要优化了,不然网上怎么会有那么多优化文章,同时还要注意团队协作资源,不能把所有的资源都给你用,不然别人还怎么干活?

所以还要在你评估的资源上再缩减一部分,这样一来一回可能需要不断的调整,这也是为什仫很多人问到怎么分配资源的时候,都会说一句靠经验!

小编觉得这玩意真的是没有公式可套用的。


如果你有更好的分配资源的方法论或者有哪里写的不对的地方,欢迎大佬联系我分享给其他小伙伴们。

如果你有其他困扰的问题,欢迎骚扰我~


参考:

  • spark官网

  • https://bbs.csdn.net/topics/392153088

相关 [spark 作业 知道] 推荐:

Spark作业不知道该如何分配资源怎么办?

- - IT瘾-dev
前几天有好几个朋友问我关于spark作业分配资源的问题:即在提交作业的时候,不知道该分配多少资源比较好. 我的回答是 靠经验,仔细想想靠经验这等于不是没说吗,总有一些方法论或者思路的吧. 所以就有了这篇文章,下笔的时候着实是不知道该怎么写,所以在网上搜索了一下,看看大佬们是怎么回答的. 赶巧了不是,还真发现3年前就有人问过这个问题.

Spark概览

- - 简单文本
Spark具有先进的DAG执行引擎,支持cyclic data flow和内存计算. 因此,它的运行速度,在内存中是Hadoop MapReduce的100倍,在磁盘中是10倍. 这样的性能指标,真的让人心动啊. Spark的API更为简单,提供了80个High Level的操作,可以很好地支持并行应用.

Spark与Mapreduce?

- - 崔永键的博客
我本人是类似Hive平台的系统工程师,我对MapReduce的熟悉程度是一般,它是我的底层框架. 我隔壁组在实验Spark,想将一部分计算迁移到Spark上. 年初的时候,看Spark的评价,几乎一致表示,Spark是小数据集上处理复杂迭代的交互系统,并不擅长大数据集,也没有稳定性. 但是最近的风评已经变化,尤其是14年10月他们完成了Peta sort的实验,这标志着Spark越来越接近替代Hadoop MapReduce了.

Spark迷思

- - ITeye博客
目前在媒体上有很大的关于Apache Spark框架的声音,渐渐的它成为了大数据领域的下一个大的东西. 证明这件事的最简单的方式就是看google的趋势图:. 上图展示的过去两年Hadoop和Spark的趋势. Spark在终端用户之间变得越来越受欢迎,而且这些用户经常在网上找Spark相关资料. 这给了Spark起了很大的宣传作用;同时围绕着它的也有误区和思维错误,而且很多人还把这些误区作为银弹,认为它可以解决他们的问题并提供比Hadoop好100倍的性能.

Spark 优化

- - CSDN博客推荐文章
提到Spark与Hadoop的区别,基本最常说的就是Spark采用基于内存的计算方式,尽管这种方式对数据处理的效率很高,但也会往往引发各种各样的问题,Spark中常见的OOM等等. 效率高的特点,注定了Spark对性能的严苛要求,那Spark不同程序的性能会碰到不同的资源瓶颈,比如:CPU,带宽、内存.

Spark&Spark性能调优实战

- - CSDN博客互联网推荐文章
       Spark特别适用于多次操作特定的数据,分mem-only和mem & disk. 其中mem-only:效率高,但占用大量的内存,成本很高;mem & disk:内存用完后,会自动向磁盘迁移,解决了内存不足的问题,却带来了数据的置换的消费. Spark常见的调优工具有nman、Jmeter和Jprofile,以下是Spark调优的一个实例分析:.

Mesos上部署spark

- - 开源小站
还是回到之前一直持续的 Mesos话题. 在之前的环节里,我们已经尝试了Mesos的安装,Marathon守护服务以及相对比较主流的Mesos作为Hadoop的资源管理器的实际操作. 这次就说说同属于伯克利出品的Spark. 其实spark最初0.7以前的版本还没有自己的资源管理系统,资源的调度都是通过Mesos来执行的.

Spark容错机制

- - zzm
一般来说,分布式数据集的容错性有两种方式: 数据检查点和记录数据的更新. 面向大规模数据分析,数据检查点操作成本很高,需要通过数据中心的网络连接在机器之间复制庞大的数据集,而网络带宽往往比内存带宽低得多,同时还需要消耗更多的存储资源. 因此,Spark选择记录更新的方式. 但是,如果更新粒度太细太多,那么记录更新成本也不低.

beeline 连接SPARK /Hive

- - 开源软件 - ITeye博客
hiveclient所在主机的jdk 1.7_51,hive 0.12和hadoop 2.3.0是从服务器端拷贝过来的,环境变量一切OK. 执行连接报了Invalid URL的错误:. 开始的一段时间都在纠结这个jdbc的URL格式问题,后来在cloudra论坛上找到了一个方法,. 直接调用的jdbc:hive2的驱动测试是正常的,证明CLASSPATH等环境变量没有问题.

Spark性能调优

- - zzm
通常我们对一个系统进行性能优化无怪乎两个步骤——性能监控和参数调整,本文主要分享的也是这两方面内容. Spark提供了一些基本的Web监控页面,对于日常监控十分有用. http://master:4040(默认端口是4040,可以通过spark.ui.port修改)可获得这些信息:(1)stages和tasks调度情况;(2)RDD大小及内存使用;(3)系统环境信息;(4)正在执行的executor信息.