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

时间:2016-06-17 00:03:13

标签: apache-spark

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

2 个答案:

答案 0 :(得分:147)

以下答案涵盖了标题中提到的3个主要方面 - 执行者数量,执行者记忆和核心数量。可能还有其他参数,如驱动程序内存和其他参数,我在此答案中未提及,但希望在不久的将来添加。

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

每个执行程序都是JVM实例。所以我们可以在一个Node中有多个执行器

操作系统和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.然后最终的数字是36 - 1,对于AM = 35

执行程序内存为:每个节点有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 ) -

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

<强>参考文献:

答案 1 :(得分:4)

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

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读取数据?

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