关于spark程序动态资源分配的一些理解

环境:

cdh5.7.1

cdh5.7.1中的spark版本为spark1.6


关于如何配置动态资源分配,参见:http://spark.apache.org/docs/1.6.3/job-scheduling.html#dynamic-resource-allocation


cloudera manager中的默认配置时开启了spark 动态资源分配的,也就是spark.dynamicAllocation.enabled=true,但是动态配置相关的默认参数好像不是很合理,比如spark.dynamicAllocation.schedulerBacklogTimeout这个参数的默认值是1秒,即当任务调度延迟超过1秒的时候,会请求增加executor,而且是指数形式的请求,比如第一次请求1个(下一次检测周期是由spark.dynamicAllocation.sustainedSchedulerBacklogTimeout这个参数来决定,默认是和spark.dynamicAllocation.schedulerBacklogTimeout一样),第二次就会请求2个,第三次4个executor。

spark.dynamicAllocation.minExecutors(默认0)和spark.dynamicAllocation.maxExecutors(默认无限大)分别来控制动态资源分配的上下线。即申请最多不会超过maxExecutors,回收executors到minExecutors,可以通过spark.dynamicAllocation.initialExecutors来设置启动的时候初始化多少个executors,不设置的话,默认初始化spark.dynamicAllocation.minExecutors个executor.

当某个executor空闲时间超过spark.dynamicAllocation.executorIdleTimeout值时(默认60秒),会回收该executor占用的资源,销毁该executor.

针对实时程序如果也要动态分配资源的话,有些默认值就需要根据实际情况调整一下了,比如spark.dynamicAllocation.initialExecutors设置成2,如果每个executor一个vcore的话,至少启动两个executor,一个core给receiver用,一个core用来执行计算任务。

另外实时程序首个batch可能会有一些初始化的动作在里面,比如初始化了数据库连接池,初始化redis连接池等等,可能处理时间会较长,如果按spark.dynamicAllocation.schedulerBacklogTimeout默认的1秒阈值的话,那么就会开始申请增加executors了,这样不是很合理,可以根据实际初始化时长适当将该参数调大一点,比如调成10秒钟。


当指定了--num-executors,即明确指定了executor的个数,即使你设置了spark.dynamicAllocation.enabled=true,动态资源分配也将无效。这点可以在driver stderr的warn日志中看到如下警告:

17/02/08 15:03:53 WARN spark.SparkContext: Dynamic Allocation and num executors both set, thus dynamic allocation disabled.
 
  
另外还是建议在spark streaming中不要采用动态资源分配,如果数据源不可靠,比如flume,在回收executor的时候可能会导致数据丢失。




你可能感兴趣的:(spark)