Hadoop YARN:调度性能优化实践
CPS是与测试压力相关的,测试压力越大,CPS可能越低。从上文公平调度器的架构可以看到,CPS跟如下信息相关:
例如,集群1000个节点,同时运行1000个App,这些App分布在500个Queue上,每个App的每个Container执行时间是1分钟。在这样的压力条件下,调度系统在有大量资源需求的情况下,每秒可以调度1000个Container。那么在这个条件下,调度系统的CPS是1000/s。 调度压力模拟器 在线上环境中,我们可以通过观察上文提到的调度系统的指标来看当前调度性能是否满足业务需求。但我们做了一个性能优化策略,不能直接到在线上环境去实验,因此我们必须有能力在线下环境验证调度器的性能是满足业务需求的,之后才能把实验有效的优化策略推广到线上环境。 那我们在线下也搭建一套跟线上规模一样的集群,是否就可以进行调度器性能优化的分析和研究呢?理论上是可以的,但这需要大量的物理机资源,对公司来说是个巨大的成本。因此我们需要一个调度器的压力模拟器,在不需要大量物理机资源的条件下,能够模拟YARN的调度过程。 社区提供了开源调度器的压力模拟工具–Scheduler Load Simulater(SLS)。 如上图,左侧是开源SLS的架构图,整体都在一个进程中,ResourceManager模块里面有一个用线程模拟的Scheduler。App和NM(NodeManager)都是由线程模拟。作业资源申请和NM节点心跳采用方法调用。 开源架构存在的问题有:
针对存在的问题,我们进行了架构改造。右侧是改造后的架构图,从SLS中剥离Scheduler Wapper的模拟逻辑,用真实的ResourceManager代替。SLS仅仅负责模拟作业的资源申请和节点的心跳汇报。ResourceManager是真实的,线上生产环境和线下压测环境暴露的指标是完全一样的,因此线上线下可以很直观地进行指标对比。 细粒度监控指标 利用调度压力模拟器进行压测,观察到validSchedule不达标,但依然不清楚性能瓶颈到底在哪里。因此需要细粒度指标来确定性能的瓶颈点。由于调度过程是单线程的,因此细粒度指标获取的手段是侵入FairScheduler,在调度流程中采集关键函数每分钟的时间消耗。目标是找到花费时间占比最多的函数,从而定位系统瓶颈。例如:在preCheck函数的前后加入时间统计,就可以收集到调度过程中preCheck消耗的时间。 基于以上的思路,我们定义了10多个细粒度指标,比较关键的指标有:
关键优化点 第一次做压测,给定的压力就是当时线上生产环境峰值的压力情况(1000节点、1000作业并发、500队列、单Container执行时间40秒)。经过优化后,调度器性能提升,满足业务需求,之后通过预估业务规模增长来调整测试压力,反复迭代地进行优化工作。 下图是性能优化时间线,纵轴为调度性能CPS。 优化排序比较函数 在核心调度流程中,第2步是排序子队列。观察细粒度指标,可以很清楚地看到每分钟调度流程总共用时50秒,其中排序时间占用了30秒,占了最大比例,因此首先考虑优化排序时间。 排序本身用的快速排序算法,已经没有优化空间。进一步分析排序比较函数,发现排序比较函数的时间复杂度非常高。 计算复杂度最高的部分是:需要获取队列/作业的资源使用情况(resourceUsage)。原算法中,每2个队列进行比较,需要获取resourceUsage的时候,程序都是现场计算。计算方式是递归累加该队列下所有作业的resourceUsage。这造成了巨大的重复计算量。 优化策略:将现场计算优化为提前计算。 提前计算算法:当为某个App分配了一个Container(资源量定义为containerResource),那么递归调整父队列的resourceUsage,让父队列的resourceUsage += containerResource。当释放某个App的一个Container,同样的道理,让父队列resourceUsage -= containerResource。 利用提前计算算法,队列resourceUsage的统计时间复杂度降低到O(1)。 (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |