背景
在做的项目BI 使用的是sparkJDBC来去查询和处理数据。依赖的SparkThiftServer这一块东西还是挺多的,今天来讲一下资源动态分配。有了资源动态分配的功能,使其在处理大数据量或者小数据量的时候,都可以处理,而且相对来说不用一直占用较多资源。
本文大部分参考官方文档,小部分是自己实际测试得出的结论。
官方文档地址:https://spark.apache.org/docs/latest/job-scheduling.html#graceful-decommission-of-executors
前置条件
使用动态资源分配的前置条件有两个
- 1、设置 spark.dynamicAllocation.enabled 为true
设置 spark.shuffle.service.enabled 为true - 2、需要在hadoop 集群配置文件修改,以及需要将spark shuffle的jar 放到NodeManager(目前只对yarn集群说明,因为最常用)
参照的官网地址:https://spark.apache.org/docs/latest/running-on-yarn.html#configuring-the-external-shuffle-service
(这块不详细说明,我们这里集群配置是好的,我这块没有实际操作过,都是公司集群,我这块就不一一说明了)
动态分配的执行机制
执行机制包括申请和废弃资源即executor
-
1、申请资源
申请资源机制为 当有还有待完成的task在等待时,当等待时长为spark.dynamicAllocation.schedulerBacklogTimeout(默认为1S)时,将触发请求来申请资源。当申请资源后还体有task在等待的时候,将每spark.dynamicAllocation.sustainedSchedulerBacklogTimeout(默认5S)再申请一次。每次申请的资源将成指数型正常,以1,2,4,8往后递推。 -
2、删除资源
删除资源这一点,当一个application闲置超过spark.dynamicAllocation.executorIdleTimeout(默认60S)的时候,将多余的executor移除。
######注意
不幸的事,在验证的时候删除资源这一点并没有验证出来,一个application在完成之后很快的将executor移除了。我不知道这块具体是什么原因。(这边走的默认的配置) 具体如下图,一秒钟就移除了。
资源调度机制
1、默认为FIFO,即先进先出的策略。官网上说当资源过大,后申请的资源会处于等待状态。
but if the jobs at the head of the queue are large, then later jobs may be delayed significantly.
但是我这边使用一个20G 资源的表进行测试,然后再去count(1)小表,这一块照样是可以运行的,所以这一块也让我很困惑。(我本来打算调优至FAIR模式,但是测试完我犹豫了。)
- 2、FAIR模式
设置spark.scheduler.mode为FAIR (FAIR 必须大写)
参数配置
这一块需要配置的参数为
./start-thriftserver.sh
–master yarn
–conf spark.driver.memory=6G
–executor-memory 9G
–executor-cores 3
–conf spark.shuffle.service.enabled=true
–conf spark.dynamicAllocation.enabled=true
–conf spark.dynamicAllocation.minExecutors=2
–conf spark.dynamicAllocation.maxExecutors=7
–conf spark.dynamicAllocation.sustainedSchedulerBacklogTimeout=3s
这一块不需要设置num-executors ,因为即使设置了 ,启动后也会根据这个参数的大小spark.dynamicAllocation.minExecutors,然后移除多余的 executor
实际应用
1、实际应用阶段的话, spark.dynamicAllocation.sustainedSchedulerBacklogTimeout 这个参数可以适当的调小,因为这是资源不够申请资源的时间,因为BI 对于时延还是有一定的要求
- 2、maxExecutors 的大小应该设置成倍数较好,就是 1+2+4 依次类推
- 3、spark.dynamicAllocation.minExecutors 根据实际分配的资源以及要处理的数据量有关。这一块的话,我们这边设置的–executor-memory 9G 和–executor-cores 3 spark.dynamicAllocation.minExecutors=2 就可以保证在数据量在1个G 是不需要去申请资源的。当然了,这一块还是要根据实际情况而定。