前言
面对复杂的业务问题,以及日益增多的需求,我们开发的脚本也越来越多,集群承载的计算量也越来越大,为了方便管理,很多企业引进或者自研出了适配的调度系统。
本节的调优办法要根据自身公司调度系统的特点,进行分析后再做出相应的调试(调优一方面追求单个作业的高效性,也要使得整体作业批次的执行时长被压缩,本节是从整体作业批次的角度来分析运行效率的)。
问题概述
以市面现有的一些开源系统中较常见的Oozie举例,其提供了定时提交任务功能以外,还能够设置作业前后置依赖,将其与Hue相集成后,能够便捷地进行开发、测试。
博主目前公司关于调度这块的技术栈就是用Oozie+Hue集成而成的,其优势很明显,就是不需要花费大量的人力成本去做调度框架的开发,调度作业的开发调试的过程可以在Hue上解决,同时Hue连接HDFS能够管理我们的作业;但是这套技术栈也会有自身的缺陷,如:对于所有作业而言,其整体的分布是去中心化的,因为我们不可能将成百上千的作业配置到一个调度中,所以对于单个作业而言,只能知道自己的前置和后置,整个作业集的分布情况是分散的。
上述的原因就导致了因人员调离、调度作业过多、描述信息缺失等问题,操作人员对处于线上的作业不知道是否还有效,是否应该被下线,这样就导致作业“只上不下”的现象发生,集群压力日益趋重。
很多公司也正是预见了这方面的问题,所以采用自主开发或者购买产品的方案,来规避这些问题。那现在这种适配性更强的调度系统底层都对计算引擎进行了封装,之所以封装是为了模板化便于管理。
本节的重点就是讲述模板化带来的不便,以及博主针对这些不便采用的修整办法。
调整办法
由于调度系统底层是模板化应用的,以spark2模式为例,对于资源开销大的job和资源开销小的job应用的submit命令是一样的,这就导致了对于某些大型job而言,就存在资源缺乏的问题。
要知道,不管是开源还是自身研发的调度系统,为了方便维护一定是运用了模板化,所以部分作业资源不够的现象一定是存在的。相对而言,大作业在调度集中总是少的,所以我们可以对着一批大作业进行调整,这里博主举个调整的例子,如调度底层应用的模板化提交命令:
spark2-submit --driver-memory 9G --executor-memory 6G --driver-cores 1 --executor-cores 1 --num-executors 11 --conf spark.memory.useLegacyMode=false --conf spark.dynamicAllocation.maxExecutors=119 --master yarn --deploy-mode client --name ${job_parth}
针对大作业,对基本参数进行调整再添加一些额外的参数指定:
spark2-submit --driver-memory 16G --executor-memory 14G --driver-cores 1 --executor-cores 4 --num-executors 60 --conf spark.scheduler.listenerbus.eventqueue.size=100000 --conf spark.executor.extraJavaOptions="-XX:+PrintGCDetails -XX:+PrintGCTimeStamps" --conf spark.sql.shuffle.partitions=400 --conf spark.memory.useLegacyMode=false --conf spark.memory.fraction=0.8 --conf spark.memory.storageFraction=0.6 --conf spark.dynamicAllocation.maxExecutors=100 --master yarn --deploy-mode client --name ${job_parth}
就博主的应用经验而言,对于非数据倾斜现象严重的大job,通过加调整资源分配方案能够成倍地提升运行效率。
结语
对于批量的调度作业而言,调整它们公共的脚本参数是压缩整体运行时长的有效办法。