Spark Yarn内存资源计算分析(参考)--Executor Cores、Nums、Memory优化配置

Spark on Yarn Executor Cores、Nums、Memory优化配置

三方面内容:executor 核心数目,executor 数量,executor 内存。对于driver memory 这个参数,设置比较灵活,一般1-8,这里不就不多说

设置以上三个参数,除了计算集群的节点数、节点Cores和内存大小外,还需要考虑以下四点因素:

spark使用yarn做资源管理,yarn后台使用一些守护进程中运行的,如NameNode,Secondary NameNode,DataNode,JobTracker和TaskTracker,因此在设置num-executors,需为每个节点预留1个core来保证这些守护进程平稳地运行。

Yarn ApplicationMaster(AM):

        AM负责从ResourceManager申请资源,与NodeManager进行通信启动/停止任务,监控资源的使用。在Yarn上执行Spark也要考虑AM所需资源(1G和1个Executor)。

HDFS Throughput:

        HDFS Client有多个并发线程写的问题,HDFS每个Executor的使用5个任务就可获取完全并发写。因此最好每个Executor的cores不高于5.

MemoryOverhead:

下面图片展示 spark-yarn-memory-usage

每个executor需要内存=spark-executor-memory+spark.yarm.executor.memoryOverhead

spark.yarm.executor.memoryOverhead=Max(384m,7%*spark.executor.memory)即大于等于384M

如果我们为每个executor申请20GB资源,实际上AM获取的资源20GB+7%*20GB=~23GB。

案例:3个节点,每个节点 8 核 + 32 GB RAM(都是真集群,1主三从)

由于每个 executor 都是一个 JVM 实例,所以我们可以给每个节点分配多个 executor。

前期准备:为系统的运行保留资源
文章原文的内容是:为了保证操作系统和 hadoop 进程的运行,每个节点要预留 1 个核心 + 1 GB 内存。所以每个节点可用的资源为:7 个核心 + 30 GB RAM。
但是如果你不希望你的系统陷入高负载的情况,你可以多预留一些资源,我个人的使用经验是每个节点预留 4 个核心 + 4 GB 内存。这块我以  6 个核心 + 28 GB (好计算)

1.确定每个 executor 的核心数量——“magic number”

executor 核心数量 = executor 能并发执行的任务(task)数量 ,研究表明,不是给 executor 分配越多的核心越好,任何一个 application 分配的核心数目超过 5 个只会导致性能下降,所以我们一般把 executor 核心数量设置为 5 及 5 以下的数字。在接下来的案例讲解中我们把核心数目设置为 3

2.设置 executor 数量
每个节点的 executor 数量 = 6(每个节点的总核心数量) / 3(每个executor 的核心数量) = 2

所以总的 executor 数量为 2(前面算的2) * 3(3个节点) = 6,由于 YARN 的 ApplicationMaster 需要占用一个 executor,所以我们设置的 executor 数量为 6 - 1 = 5

注意:单次提交任务至少需要2核,即一个executor和一个driver(本质是也是executor)

3.设置 executor 分配的内存大小
在之前的步骤中,我们给每个节点分配了 2个 executor,每个节点可用的 RAM 是 28GB,所以每个 executor 的内存为 28 / 2 = 14 GB。
但是 spark 在向 YARN 申请内存时,YARN 会给每个 executor 多分配大小为 overhead 的内存,而 overhead = max(384 MB, 0.07 * spark.executor.memory)

在我们的案例中 overhead = 0.07 * 14 = 0.98 GB > 384 MB,所以我们申请的内存大小为 14 - 0.98  ~  13 GB

driver:内存(1~13G)

最终我们得到的分配方案是:每个 executor 分配 3 个核心,设置 5 个 executor, 每个 executor 分配的内存为 13 GB。写成 spark-submit 命令为:

spark-submit
 --master yarn
 --num-executors 3
 --executor-memory 13
 --executor-cores 3 (这个代表每个executor核个数)

这个只提供一个计算方式,并不代表是最优的,可以自行进行计算

注意:driver:内存(1~13G),这个需要注意一下,我们需要先设置container的参数大小,否则会报错,具体看下面

扩展:理解2个配置项详解:

yarn.nodemanager.resource.memory-mb

从这个参数开始,我们来看 NodeManager 的配置项。这个参数其实是设置 NodeManager 预备从本机申请多少内存量的,用于所有 Container 的分配及计算。这个参数相当于一个阈值,限制了 NodeManager 能够使用的服务器的最大内存量,以防止 NodeManager 过度消耗系统内存,导致最终服务器宕机。这个值可以根据实际服务器的配置及使用,适度调整大小。

比如上面的那个算法:我们为 NodeManager 分配了 28GB 的内存。

yarn.scheduler.maximum-allocation-mb
单个容器(container)可申请的最大内存资源,应用在运行时申请的内存不能超过这个配置项值,因为这个配置项是指定一个container最大的内存,实际分配内存时并不是按照这个配置项分配,所以这个配置项可以配置成和nodemanager的可用内存(yarn.nodemanager.resource.memory-mb)一样即可,这样的话,意味着只要这个节点的nodemanager可用内存哪怕只够跑一个container,这个container也是可以启动的。

参考链接:

https://blog.csdn.net/wx6gml18/article/details/111433509

https://www.jianshu.com/p/c9d955bc99db?utm_campaign=maleskine&utm_content=note&utm_medium=reader_share&utm_source=weixin

 

<think>嗯,用户想了解如何在给定的spark2-submit命令中添加动态资源关闭的配置。首先,我需要回忆一下Spark中关于动态资源分配的相关参数。动态资源分配允许Spark根据工作负载动态调整executor的数量,这样可以更有效地利用集群资源。相关的配置选项通常以spark.dynamicAllocation开头。 用户提供的命令已经包含了一些配置,比如spark.port.maxRetries、spark.sql.shuffle.partitions等。现在需要找到合适的位置插入动态资源分配的参数。根据Spark文档,启用动态资源分配需要设置spark.dynamicAllocation.enabled为true,然后可能需要设置其他相关参数,比如最小和最大executor数量,初始executor数,以及executor的空闲超时时间。 常见的配置项包括: - spark.dynamicAllocation.enabled=true - spark.dynamicAllocation.minExecutors=... - spark.dynamicAllocation.maxExecutors=... - spark.dynamicAllocation.initialExecutors=... - spark.dynamicAllocation.executorIdleTimeout=...s 需要检查用户当前的命令是否已经指定了--num-executors,因为动态分配开启后,maxExecutors可能这个参数相关。在用户的命令中,--num-executors是设置为$max_executors,所以可能需要将spark.dynamicAllocation.maxExecutors也设置为同样的变量,或者根据情况调整。不过,如果动态分配启用,可能不需要再指定--num-executors,但需要确认。 另外,用户提到要“新增动态资源关闭命令”,可能是指如何正确关闭不再需要的executors。这时候,除了启用动态分配外,还需要确保有正确的超时设置,使得空闲的executors能够被释放。比如,设置executorIdleTimeout,默认可能是60s,但可以根据需要调整。 接下来,需要确定将这些参数添加到命令的哪个位置。通常在--conf参数后面添加。例如,在现有的--conf参数之后,继续添加新的--conf设置。 可能的添加位置是在现有的--conf之后,比如: --conf spark.dynamicAllocation.enabled=true \ --conf spark.dynamicAllocation.minExecutors=1 \ --conf spark.dynamicAllocation.maxExecutors=$max_executors \ --conf spark.dynamicAllocation.executorIdleTimeout=60s \ 需要注意,用户已经指定了--num-executors $max_executors,但在动态分配启用后,maxExecutors应该之保持一致,或者根据需求调整。此外,如果用户希望保留固定数量的executors,可能需要调整这些参数,但通常动态分配会根据负载自动增减。 还需要确认是否需要设置shuffle服务,因为动态资源分配需要外部的shuffle服务支持,特别是在YARN集群上。可能需要配置spark.shuffle.service.enabled=true,并确保YARN的NodeManager配置了对应的shuffle服务。如果用户的环境中已经配置好了,那么只需要启用相关选项;如果没有,可能需要额外的步骤,但用户的问题只是关于命令行参数的添加,所以可能只需要添加基本的动态分配参数。 综上,应该在现有的--conf参数部分添加动态资源分配的相关配置,确保动态分配启用,并设置合适的min/max executors以及超时时间。同时,可能需要调整原有的--num-executors参数,但根据Spark的文档,当动态分配启用时,--num-executors会被忽略,除非设置了initialExecutors。因此,可能需要将--num-executors替换为initialExecutors,或者保留,但需要测试确认。 不过,用户希望的是在现有命令中新增配置,而不是修改已有参数。因此,直接添加动态分配相关的--conf参数即可,同时保留原有的--num-executors,但需要注意是否会有冲突。根据Spark配置优先级,命令行参数优先级最高,所以如果有冲突,命令行参数会覆盖其他配置。但为了保险起见,最好将maxExecutors设置为和--num-executors相同的值,或者根据需求调整。 最终,在用户的命令中,应该在--conf部分添加以下参数: --conf spark.dynamicAllocation.enabled=true \ --conf spark.dynamicAllocation.minExecutors=1 \ --conf spark.dynamicAllocation.maxExecutors=$max_executors \ --conf spark.dynamicAllocation.executorIdleTimeout=60s \ --conf spark.shuffle.service.enabled=true \ 不过,spark.shuffle.service.enabled可能需要根据集群是否配置了外部shuffle服务来决定是否开启。如果用户的环境没有配置,那么开启这个会导致错误,所以可能需要用户确认环境是否支持。但通常在使用YARN的情况下,可以启用这个配置,前提是集群已经正确设置。 因此,在不确定的情况下,可能建议用户添加前四个参数,并提示关于shuffle服务的注意事项。但根据常见配置,可能还是需要包括shuffle服务的启用。 总结,修改后的命令应该在适当的位置(通常在现有的--conf之后)添加动态资源分配的配置,包括启用、min/max executors、空闲超时以及shuffle服务启用。</think>以下是添加了动态资源关闭配置后的命令及分步解释: 原始命令修改后的版本: ```bash /usr/bin/spark2-submit \ --queue root.yarn_appcc \ --jars $libpath/ojdbc14-10.2.0.4.0.jar,$libpath/OracleDateTypeInit.jar,$libpath/mysql-connector-java-5.1.39.jar,$libpath/aviator-4.2.8.jar \ --files $confFileName \ --conf spark.port.maxRetries=256 \ --conf spark.sql.shuffle.partitions=200 \ --conf spark.rpc.netty.dispatcher.numThreads=10 \ --conf spark.driver.extraJavaOptions="-XX:PermSize=2g -XX:MaxPermSize=2g -Xss4096k" \ # 新增动态资源分配配置 ↓↓↓ --conf spark.dynamicAllocation.enabled=true \ --conf spark.dynamicAllocation.minExecutors=1 \ --conf spark.dynamicAllocation.maxExecutors=$max_executors \ --conf spark.dynamicAllocation.executorIdleTimeout=60s \ --conf spark.shuffle.service.enabled=true \ # 新增动态资源分配配置 ↑↑↑ --num-executors $max_executors \ --executor-cores $max_cores \ --executor-memory ${executor_memory}G \ --driver-memory 6G \ --class $fullclassname \ $jarname $startDate $endDate ``` 分步解释: 1. **启用动态分配核心参数** ```bash --conf spark.dynamicAllocation.enabled=true ``` - 基础开关,必须设置为true才能启用动态资源分配 2. **Executor数量边界控制** ```bash --conf spark.dynamicAllocation.minExecutors=1 \ --conf spark.dynamicAllocation.maxExecutors=$max_executors ``` - `minExecutors=1`:保证至少保留1个executor防止任务中断 - `maxExecutors=$max_executors`:原有`--num-executors`参数值保持一致,控制资源使用上限 3. **资源释放策略** ```bash --conf spark.dynamicAllocation.executorIdleTimeout=60s ``` -executor空闲60秒后自动释放 - 可根据集群负载调整该值(生产环境通常设60-120s) 4. **Shuffle服务支持** ```bash --conf spark.shuffle.service.enabled=true ``` - 必需配置!确保释放executor时不会丢失shuffle数据 - 需确认YARN集群已部署`spark_shuffle`服务 注意事项: 1. 原有`--num-executors`参数会作为初始executor数量 2. 建议在YARN队列中设置`最大资源使用量 = maxExecutors * (executor-memory + overhead)` 3. 监控日志中应有`INFO scheduler.DynamicAllocationExecutorAllocator: Request to remove executorIds`这类资源释放记录 效果示例: 当任务出现阶段性负载波动时(如先做数据读取后进行计算): $$ \text{执行阶段} \rightarrow \text{自动扩容} \uparrow \rightarrow \text{空闲阶段} \rightarrow \text{自动缩容} \downarrow $$ 通过动态调整executor数量,可提升集群资源利用率约30%-50%(根据任务特性不同)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alex_81D

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值