
# 配置Yarn模式下Spark动态资源调度
#### 操作场景
对于Spark应用来说，资源是影响Spark应用执行效率的一个重要因素。当一个长期运行的服务（比如JDBCServer），如果分配给它多个Executor，可是却没有任何任务分配给它，而此时有其他的应用却资源紧张，这就造成了很大的资源浪费和资源不合理的调度。
动态资源调度就是为了解决这种场景，根据当前应用任务的负载情况，实时的增减Executor个数，从而实现动态分配资源，使整个Spark系统更加健康。
动态资源调度需配合External Shuffle Service使用，否则Executor销毁后Shuffle数据会丢失。
#### 操作步骤
1. 使用动态资源调度功能前，Spark必须已配置External Shuffle Service，具体可以参考[使用External Shuffle Service提升性能](https://support.huaweicloud.com/devg-mrs/mrs_06_0225.html)。
   
   在Spark中，External Shuffle Service（外部 Shuffle 服务）是一个独立于Executor的进程，主要用于优化Shuffle操作的性能和稳定性。它通过将Shuffle数据的管理从Executor中剥离出来，解决了Executor退出时Shuffle数据丢失的问题，同时减少了资源竞争。
   
   
2. 登录FusionInsight Manager，选择"集群 \> 服务 \> Spark2x \> 配置 \> 全部配置"。在搜索框中输入"spark.dynamicAllocation.enabled"参数名称，将JDBCServer下的该参数值设置为"true"，表示开启动态资源调度功能。 
   下面是一些可选配置，如[表1]所示，可根据实际情况进行调整。
    表1动态资源调度参数 
   | **配置项**                                                  | **说明**                                                                                                                                                                                                                                  | 取值示例                                                                                                                                                                                                                                                                                                 |
   |:---|:---|:---|
   | spark.dynamicAllocation.minExecutors                     | 动态分配时保留的Executor最小数量。 当启用动态分配时，Spark会根据作业负载自动调整Executor数量，但始终会保留至少指定个数的Executor，以保证基本的计算资源。 建议根据最小负载设置一个合理值，如1。                                           | 0                                                                                                                                                                                                                                                                                                    |
   | spark.dynamicAllocation.initialExecutors                 | Spark动态资源分配中用于设定作业启动时初始分配的Executor数量。 在应用启动阶段，根据预估负载预先分配Executor，避免初期因资源不足导致的任务延迟。 需满足大等于"spark.dynamicAllocation.minExecutors"且小等于"spark.dynamicAllocation.minExecutors"。 | 0                                                                                                                                                                                                                                                                                                    |
   | spark.dynamicAllocation.maxExecutors                     | 单个Spark应用程序最多可占用的Executor数量上限。 当启用动态分配时，Spark会根据作业负载自动调整Executor数量，但不会超过该参数设定的值，以此控制资源使用的上限，防止资源滥用，保护集群中其他任务。                                                                                              | 2048                                                                                                                                                                                                                                                                                                 |
   | spark.dynamicAllocation.schedulerBacklogTimeout          | Spark动态资源分配中用于控制何时触发Executor扩容。 当等待执行的Task队列长度超过该时间阈值仍未处理时，Spark会请求分配更多的Executor以加速处理。                                                                                                                    | 1s                                                                                                                                                                                                                                                                                                   |
   | spark.dynamicAllocation.sustainedSchedulerBacklogTimeout | Spark动态资源分配中用于控制持续性扩容Executor的时间阈值。 当等待执行的Task队列持续积压超过该时间时，Spark会继续增加Executor数量，直到达到maxExecutors。 通常建议设置比首次超时时间更长。                                                          | 1s                                                                                                                                                                                                                                                                                                   |
   | spark.dynamicAllocation.executorIdleTimeout              | 当Executor处于空闲状态（无任务运行）时，等待多久后将其销毁。 当Executor长时间无任务执行时，Spark会将其释放以回收集群资源，避免资源浪费。                                                                                                                            | 60s                                                                                                                                                                                                                                                                                                  |
   | spark.dynamicAllocation.cachedExecutorIdleTimeout        | Spark动态资源分配中的用于控制包含cached blocks的Executor空闲超时时间。 与普通Executor不同，这类Executor在空闲时会被保留更长时间，以避免缓存数据丢失导致的重新计算开销。                                                                                                   | - JDBCServer：2147483647s  - IndexServer：2147483647s  - SparkResource：120   |
      
   
   
 
