[英]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.