繁体   English   中英

如何调整spark执行器编号,内核和执行程序内存?

[英]How to tune spark executor number, cores and executor memory?

你从哪里开始调整上面提到的参数。 我们从执行程序内存开始并获取执行程序的数量,或者从核心开始并获取执行程序编号。 我按照链接 但是有一个高层次的想法,但仍然不确定如何或从哪里开始并得出最终结论。

以下答案涵盖了标题中提到的3个主要方面 - 执行程序数,执行程序内存和核心数。 可能还有其他参数,如驱动程序内存和其他一些我在本答案中没有解决的问题,但是想在不久的将来添加。

案例1硬件 - 6个节点,每个节点16个内核,64 GB RAM

每个执行程序都是JVM实例。 因此,我们可以在单个节点中拥有多个执行程序

OS和Hadoop守护程序需要前1个核心和1 GB,因此每个节点可以使用15个核心,63 GB RAM

从如何选择核心数开始

Number of cores = Concurrent tasks as executor can run 

So we might think, more concurrent tasks for each executor will give better performance. But research shows that
any application with more than 5 concurrent tasks, would lead to bad show. So stick this to 5.

This number came from the ability of executor and not from how many cores a system has. So the number 5 stays same
even if you have double(32) cores in the CPU.

执行人数:

Coming back to next step, with 5 as cores per executor, and 15 as total available cores in one Node(CPU) - we come to 
3 executors per node.

So with 6 nodes, and 3 executors per node - we get 18 executors. Out of 18 we need 1 executor (java process) for AM in YARN we get 17 executors

This 17 is the number we give to spark using --num-executors while running from spark-submit shell command

每个遗嘱执行人的记忆:

From above step, we have 3 executors  per node. And available RAM is 63 GB

So memory for each executor is 63/3 = 21GB. 

However small overhead memory is also needed to determine the full memory request to YARN for each executor.
Formula for that over head is max(384, .07 * spark.executor.memory)

Calculating that overhead - .07 * 21 (Here 21 is calculated as above 63/3)
                            = 1.47

Since 1.47 GB > 384 MB, the over head is 1.47.
Take the above from each 21 above => 21 - 1.47 ~ 19 GB

So executor memory - 19 GB

最终号码 - 执行者 - 17,核心5,执行者内存 - 19 GB


案例2硬件:相同的6节点,32核,64 GB

5对于良好的并发性是相同的

每个节点的执行者数量= 32 / 5~6

因此总执行器= 6 * 6节点= 36.然后,对于AM = 35,最终数字为36-1

执行程序内存为:每个节点有6个执行程序。 63 / 6~10。 头顶是.07 * 10 = 700 MB。 所以四舍五入为1GB,我们得到10-1 = 9 GB

最终号码 - 执行者 - 35,核心5,执行者内存 - 9 GB


案例3

上述场景始于接受固定的核心数量并转移到执行器和内存的数量。

现在对于第一种情况,如果我们认为我们不需要19 GB,只有10 GB就足够了,那么下面是数字:

每个节点的核心5#执行者= 3

在这个阶段,根据我们的第一次计算,这将导致21,然后是19。 但是因为我们认为10是好的(假设开销很小),那么我们不能将每个节点的执行者#切换到6(如63/10)。 当我们只有16个核心时,每个节点有5个执行器,5个核心每个节点有30个核心。 因此,我们还需要更改每个执行程序的核心数。

所以再次计算,

幻数5变为3(任何小于或等于5的数字)。 因此,有3个内核和15个可用内核 - 每个节点有5个执行器。 所以(5 * 6 -1)= 29位遗嘱执行人

因此内存为63 / 5~12。头部为12 * .07 = .84因此执行程序内存为12 - 1 GB = 11 GB

最终数字是29个执行器,3个核心,执行程序内存为11 GB


动态分配:

注意:如果启用了动态分配,则执行程序数量的上限。 因此,如果需要,火花应用程序可以消耗掉所有资源。 因此,在您正在运行其他应用程序并且还需要核心来运行任务的群集中,请确保您在群集级别执行此操作。 我的意思是您可以根据用户访问权限为YARN分配特定数量的核心。 因此,您可以创建spark_user,然后为该用户提供核心(最小/最大)。 这些限制用于在YARN上运行的spark和其他应用程序之间共享。

spark.dynamicAllocation.enabled - 当它设置为true时 - 我们不需要提及执行程序。 原因如下:

我们在spark-submit时提供的静态参数号用于整个作业持续时间。 然而,如果动态分配出现,那么会有不同的阶段

什么开始:

要开始的执行者的初始数量( spark.dynamicAllocation.initialExecutors

多少 :

然后根据负载(待处理的任务)请求多少。 这最终将是我们以静态方式提供spark-submit的数字。 因此,一旦设置了初始执行程序编号,我们将转到min( spark.dynamicAllocation.minExecutors )和max( spark.dynamicAllocation.maxExecutors )数字。

什么时候问或给:

我们何时请求新的执行程序( spark.dynamicAllocation.schedulerBacklogTimeout ) - 在这么长的时间内有待处理的任务。 所以要求。 每轮请求的执行者数量与上一轮相比呈指数增长。 例如,一个应用程序将在第一轮中添加1个执行程序,然后在后续轮次中添加执行程序中的2,4,8等。 在特定点上,上面的最大值出现了

我们什么时候放弃执行者( spark.dynamicAllocation.executorIdleTimeout ) -

如果我错过任何事情,请纠正我。 以上是基于我分享的博客和一些在线资源的理解。 谢谢。

参考文献:

此外,它取决于您的用例,一个重要的配置参数是:

spark.memory.fraction (用于执行和存储的(堆空间 - 300MB)的分数)来自http://spark.apache.org/docs/latest/configuration.html#memory-management

如果您不使用缓存/持久性,请将其设置为0.1,这样您就拥有了程序的所有内存。

如果使用缓存/持久性,则可以检查以下内存:

sc.getExecutorMemoryStatus.map(a => (a._2._1 - a._2._2)/(1024.0*1024*1024)).sum

您是从HDFS还是从HTTP读取数据?

同样,调整取决于您的用例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM