如何开始调整上述参数。我们是从执行器内存和执行器数量开始,还是从核心数开始获取执行器数量。我遵循了 链接 ,但只得到了一个高级别的想法,仍然不确定如何或从何处开始,并达成最终结论。
如何开始调整上述参数。我们是从执行器内存和执行器数量开始,还是从核心数开始获取执行器数量。我遵循了 链接 ,但只得到了一个高级别的想法,仍然不确定如何或从何处开始,并达成最终结论。
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
案例2 硬件: 相同的6个节点,32个核心,64 GB
5对于良好的并发性是相同的
每个节点的执行器数量= 32/5〜6
因此总执行器数= 6 * 6个节点= 36。然后最终数字为36-1用于AM = 35
执行器内存为:每个节点6个执行器。63/6〜10。开销为0.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)。因为每个节点有6个执行器和5个核心时,它会降至每个节点30个核心,而我们只有16个核心。因此,我们还需要更改每个执行器的核心数。
因此再次计算,
神奇的数字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。动态分配:
注意:如果启用了动态分配,则执行器数量的上限。这意味着Spark应用程序可以在需要时占用所有资源。因此,在运行其他应用程序并且它们也需要核心来运行任务的群集中,请确保您在群集级别上执行此操作。我的意思是,您可以根据用户访问为YARN分配特定数量的核心。因此,您可以创建spark_user,然后为该用户提供核心(最小/最大)。这些限制是为Spark和在YARN上运行的其他应用程序之间共享而设置的。
spark.dynamicAllocation.enabled - 当设置为true时 - 我们无需提及执行器。原因如下:
我们在spark-submit中给出的静态参数是整个作业持续时间的参数。但是,如果涉及到动态分配,则会有不同的阶段,例如
从哪里开始:
初始执行器数(spark.dynamicAllocation.initialExecutors)
多少个:
根据负载(待处理任务)确定需要请求多少个执行器。这最终将是我们以静态方式在spark-submit中提供的数字。因此,一旦设置了初始执行器数量,我们就会使用最小值(spark.dynamicAllocation.minExecutors)和最大值(spark.dynamicAllocation.maxExecutors)的数字。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读取数据?
再次强调,调优取决于你的使用情况。
spark.memory.storageFraction=0.1
?因为据我所知,spark.memory.fraction
决定了 Spark
用于 执行和存储 的内存量(您已经提到了这一点),只有可用于存储和执行的内存的 spark.memory.storageFraction
是免受 缓存驱逐 的影响。请参见此链接。 - y2k-shubham