摘要: TPP(Taobao Personalization Platform, 也称阿里推荐平台) 平台承接了阿里集团 300 + 重要个性化推荐场景,包括手淘首页猜你喜欢、首图个性化、购物链路等。除了提供应用层面的支持和封装,还肩负着机器分配和维护各场景运行稳定的重任。
基于如上的两点:日常的时候提高资源利用率,大促的时候解放人力,TPP 智能调度系统就产生了。TPP 智能调度系统以每个集群(一组机器,承载一个或多个场景)的 CPU 利用率,LOAD,降级 QPS,当前场景 QPS,压测所得的单机 QPS 为输入,综合判断每个集群是否需要增加或者减少机器,并计算每个场景需要增减机器的确切数目,输出到执行模块自动增减容器。 TPP 智能调度系统有如下的贡献点:
该系统由 TPP 工程团队和猜你喜欢算同学联合搭建而成,从 2017 年 9 月开始规划,到 10 月 1 日小批量场景上线,到 10 月 13 日三机房全量上线;经过一个月的磨合,参加了 2017 年双 11 当天从 00:15 % 到 23:59 的调度,峰值 QPS 达到百万级别。在日常运行中,集群平均 CPU 利用率提高 3.37 倍, 从原来平均 8% 到 27%;在大促期间,完成造势场景,导购场景和购后场景的错峰资源调度,重要服务资源利用率保持在 30% ,非重要服务资源利用率保持在 50%, 99% 的重要场景降级率低于 2%。同时 TPP 智能调度系统的 "时间录入" 功能支持定时活动,如首页红包的提前录入,提前扩容,活动结束收回机器,改变了以前每天需要定时手动分机器的情况。
TPP 智能调度系统要解决的问题为: 如何在机器总数有限的前提下,根据每一个场景上核心服务指标 KPI(异常 QPS 等)和场景所在集群物理层指标 KPI(CPU,IO 等),最优化每一个场景机器数目,从而使得总体资源利用率最高。
更加直白一点,就是回答如下的问题:
TPP 智能调度涉及 TPP 的各方各面,其架构图如下所示,包括数据输入、算法决策和决策执行三个方面,但是为了更灵敏的、更及时的发现超载的场景并进行扩容,需要自动降级、秒级扩容、单机压测 qps 预估功能的保证。另外还有一些功能性的开发,如业务算法配置参数分离、调度大盘监控、烽火台规则运行平台等的支持。最底层的更加离不开容器化的全量部署 ,使得加减机器,快速部署环境成为了可能。
智能调度的算法是在其他模块都具备的情况下,才能够稳定有效的运行。因此在介绍智能调度算法之前,先对算法依赖的每个部分进行简要的介绍如下。
KMonitor 是基于 optsdb on druid 架构的监控系统。支持从 Hippo,amon 和 Log 文件收集监控数据, 并可以在 grafana 上展示或是通过 api 接口获取。 TPP 调度系统对 Kmonitor 的使用包括两部分: 通过 tpp 的 log 文件注册 tpp 服务的状态信息和调度系统从 Kmonitor 获取状态信息。 目前注册的状态信息包括容器内的 cpu/load 等系统状态和每个场景的 pv/latency 等业务信息. 通过使用 kmonitor 提供的多租户功能, tpp 独立部署了一套租户系统, 可以支持信息汇报延迟不超过 5s。调度系统获取这部分信息后作为计算的数据输入。
2017 年 TPP 全部集群运行在 Fiber 之上,Fiber 是在 Hippo 机器调度系统的一种封装,其优势在于能够将容器的加载、预热、上线维持在秒级别,而之前直接从 Hippo 调度机器,加载方案到正常上线需要 10 分钟级别。Fiber 本身可以配置 buffer,每个一定时间将重要的 P1 场景加载到 buffer 中的机器上并定时预热,通过实践验证,在提前有 buffer 预热的情况下,从智能扩缩容发出扩容指令开始到机器完全挂上去,能够在 10s 内完成。
自动降级是 2017 年 TPP 双 11 的另外一个创新,其主要的思想是判断当天集群总的超时 QPS 的比例,如果从全局上统计超过用户设置的阈值(如 3 秒钟区间统计值超过 1%),则将出现超时的容器集体降级。 所谓降级是指方案的一个新的配置,高级别的运行配置保证更好的展示效果,但是单容器能够服务的 QPS 较少;低级别的运行配置会使得展示效果打折扣,但是单容器能够服务的 QPS 会更多。举个例子:首页猜你喜欢 L0 的配置是访问 RTP,利用深度模型进行 item 的打分,L1 则会关闭 RTP 访问的开关,从而节省 CPU,服务更多的 QPS,但是可能从业务上来看,展示的 item 的相关度会打折扣。
自动降级主要用在如下两个方面:1. 双 11 在 0 点峰值附近的时候,整个集群机器严重不足,可以通过集体配置降级,保证全部用户能够正常访问,即使服务质量稍有下滑,但是和超时相比,是可以忍受的; 2. 是和智能扩缩容相关的。智能扩缩容的出现,使得一天中集群的机器数目会发生更频繁的变化,而 JVM 容器本身存在预热的问题,当一个新的容器挂载到线上知道 100% 预热完成之前,就会出现严重的超时。有了自动降级之后,可以通过砍掉一部分二方服务的 rt,使得即使预热的 QPS 也不会严重超时,从而消减了扩容瞬间对线上 QPS 的影响。当然不同的场景其预热过程要详细的优化,有 CPU 密集的、IO 密集的、以及缓存型的,其预热过程得有所不同。
场景压测在每天夜里定时执行,获取场景的单机性能。对于具备降级配置的场景,会压测每一套降级配置的性能。针对每个场景,当场景 owner 将场景加入日常压测列表,自动压测程序将会于每晚凌晨 0:00 调用 API,获得压测列表,创建待压测场景的影子场景,申请压测发生容器,调用压测接口逐渐增加 qps,直至容器超出负载(系统 load,cpu,业务异常率等)。目前 CPU 上限为 100%,异常率的上限为 5%。 该运行结果就可以作为 TPP 智能调度的输入,作为每个场景在某个特定的级别(L0、L1、L2 或者 L3)的单机服务能力。压测结果如下所示:
在上述模块稳定保障下,智能调度算法形式化为资源调度优化问题:
约束条件为:
智能调度算法核心要解的问题是:尽可能的通过给不同的场景加减机器,改变所有场景的 CPU 的值,将所有集群的 CPU 调节到目标 CPU(人工设定优化目标)的周围, 并且尽可能的均衡。如两个场景,目标 CPU 为 40%。将其调节为 38%、42%,肯定要比 10%、70% 要好。这个均衡的程度是由优化目标来决定的。
在最开始算法考察的过程中,还考虑过别的一些算法,比如分层的背包方法,包的容量是 "总的机器池子的 quota",每个集群是要放在书包里面的物品,放到里面会消耗一定的机器,消耗了背包的 "空间", 但是同时加了机器,CPU 降低会带来一定的增益:优化目标变小。暴力搜索也是可以在有限时间解这个问题的。
但是我们最后还是采用了一种朴素的做法,尽可能的模拟人进行调度的方法,对需要机器的场景排个序,用不重要场景的机器拿出机器去补充重要 P1 场景。可以根据人为的经验去灵活调整扩缩容次序,因为在实际运行过程中,可解释性永远比最优化更重要,你给一个场景加了机器,减了机器,需要给人家解释清楚。而不是说,给某个集群拿掉 10 台机器是因为集群总的负载均衡度上升了 0.01。
更加详细的介绍智能调度的算法如下。我们直接计算每一个集群 CPU 到达最优解需要的机器数 Ni, 如果 Ni>0,表示需要扩充机器降低 CPU 到目标 CPU,如果 Ni < 0, 表示可以拿掉机器提高场景 CPU 到目标 CPU。有如下的几种情形:
1. 如果所有 Ni 的和 < 空闲机器, 即集群空闲的机器数目加上可以缩出来机器大于所有要机器的数目,那所有的需要扩容的都可以到达目标 CPU,所有缩容的直接拿掉机器 CPU 升高到目标 CPU,也就是优化目标达到最小值 0。
2. 如果所有 Ni 的和 > 空闲机器, 即扩容需求不能得到完全满足。这时调度算法会选择满足限制条件,并且使得优化目标函数变化最小的梯度方向进行变动。 具体方法是:将所有的非 P1 场景通过降级或者提高目标 CPU 水位,使其需要的机器变少,甚至可以拿出机器。然后进行如下迭代:每次选择能够拿出机器最多的场景,将其机器加到需要机器最少、优先级最高的场景上,使其 CPU 达到目标 CPU。然后将扩容被满足的场景从 list 中移除。重复如上步骤,直到所有能够拿出的机器被用完。"优化目标函数变化最小的梯度" 是这样体现的:尽可能少的降级非 P1 或者提高非 P1 场景的水位,尽可能多的满足 P1 场景。
3. 第 2 步可能有两种结果,所有 P1 的扩容需求被满足,算法有解。否则算法无解,优化目标也没有指导意义了,只能尽可能的满足部分 P1, 不能满足的 P1 只能被降级。这种无解的情况只有在大促次峰值附近出现过极少数时间。
上述算法的复杂度为 O(m) , m 为被调度的集群的个数,量级为 1000,因此每次都能很快得出近似最优解,计算开销很小。
除了上述的寻找最优值的算法,智能调度算法还有两个关键模块需要介绍:收敛逻辑和 Ni 的计算。
智能调度算法运行的控制逻辑是,设置迭代间隔,如每隔 5 秒进行一次迭代。每一轮迭代中,拿到场景实时的状态信息,场景 "过载" 了给扩容,场景 "空载" 了给缩容,不论是扩容还是缩容,在扩的过程中,要时刻监控关键指标是否到了目标区域,从而结束本轮迭代。这类控制逻辑,最重要的是要保证是收敛的,即不论怎么调整,最终会较快达到稳态; 同时,不论系统何时、何种程度偏离稳态,都是可以自己重新恢复到稳态。
线上实验表明,目前最可靠的收敛方式是为集群设置稳态区间。如设置的区间为 [20%,40%], 如果 cpu 超出稳态区间,大于 40%,则加机器,等到下一轮迭代,判断 cpu 是否在稳定区间,如果是则停止调节;如果加机器加过头了,cpu 跌出了 20%, 则减机器,让 cpu 回升,经过多轮迭代,最终达到稳态。理论上,稳态区间设置越大,收敛的速度会越快,基本不会出现扩容扩过头的情况,在比较好的计算所需机器的算法支持下,一次就可以收敛。但是过宽的稳态区间会使得资源利用率较低,有可能集群是在下线水位运行。
另一个极端就是稳态区间设置成为一个值,指哪打哪,比如目标 cpu 设置成为 30%,如果 CPU 大于 30%,就会扩容,如果 CPU 小于 30%,缩容。这样的好处是,集群 CPU 肯定在 30% 附近波动,平均下来,集群 CPU 达到目标值 30%,但是这样的缺点就是频繁的增减机器,增加机器并不是没有开销,运行 JVM 的容器存在预热问题,冷机器上线会增加异常 QPS 的比例,是得不偿失的。经过实际运行,我们选定 optimalCPUDrift=2, 也就是在目标 CPU 的 + 2 和 - 2 的区间都是稳态,既能使得集群 CPU 达到目标值,同时又能避免频繁扩缩容。
Ni 计算公式
Ni 表示一个场景机器数目的变动,Ni>0 表示需要机器,Ni<0 表示可以被缩容。Ni 有两种计算方式:
第一种计算方法是根据单机压测的 QPS 来计算,非常直观,因为单机 QPS 是通过线下不停的增加流量,一直到该单机 CPU 到达 100% 或者异常 QPS 超过 5%,但在真实使用的过程中发现,线下的压测数据通常和线上真实能够服务的 qps 不太一样,主要原因有两个:一个是线上有可能是多个场景公用一个物理机,互相影响;另外一个是线下压测只能是天级别的数据,但是有可能当一个场景发生了方案更改,其服务能力也会发生变化,而压测数据还是历史值。
第二种计算方法采用的是当前实时的结果,较为准确。唯一的缺点的是会受到噪音 CPU 的影响,如刚扩上去的机器,由于预热的原因,CPU 会瞬间飙高,等完全预热了之后 CPU 才会降下来,这种问题的解决方法刚加上去的机器在预热期间不输出 CPU 的数据,免得影响 Ni 的计算。
扩容的触发条件
有了计算 Ni 的方法了之后,下一步需要关注的就是何时触发扩容,然后计算 Ni。 目前智能调度算法的触发条件有两个:
1、当目前 1 分钟的平均 CPU 不在稳态区间中。 此时:
2. 当一个场景降级的 QPS 比例大于一定阈值,线上取 5%。由于降级触发的扩容,其:
最终的:
其他功能
除了大盘,还进行了机器的热点和调度可视化,能够在双 11 当天更方面的监控集群的运行状态。下图中一个格子表示一个集群,颜色表示 CPU 水位,大小表示拥有机器数目。当有场景被扩容或者缩容时也会可视化出来。
下图取了 10 月 1 日(智能调度上线前)和 11 月 6 日(智能调度上线后)24 小时内首页猜你喜欢的机器数、CPU 利用情况对比(其中机器数和 QPS 做了归一化处理):
从上图中可以看出,在运行了智能调度 (红色线) 之后,CPU 利用率从原来持续低于 15%,平均 CPU 利用率 8% 提高到平均 27%。值得指出的是,为了保护场景,智能调度设置了最小机器数的保证,数目为 max {3 台机器,过去 24 小时机器平均值},所以在凌晨 1 点到凌晨 7 点,即使 QPS 变为个位数, 场景机器没有被完全拿空。如果有离线在线混部的需求,可以把凌晨的机器保护去掉,让这些机器回归机器池子,部署机器学习训练模型。
同时我们可以看出来,运行了智能调度之后,日常的机器数是原来固定分配机器的 1/3,极大的节省了机器资源。
智能调度和固定机器相比,缺点就是会在一天中,比较频繁的发生机器数目的变动,但是通过图 (d) 的统计,可以看出超时 qps 能够持续小于千分之 2,处在可以接受的范围内。
在上图中,我们选择了四个场景,记录了它们在双 11 当天 24 小时的 CPU、集群机器数、QPS(对数刻度)、超时 QPS 比例的变化图。从上面第二个子图可以看出来四个场景明显的错峰资源调度,蓝色线在 10 点需要机器,但是后面机器贡献出来提供给绿色的场景来使用。此外,从第二张子图可以看出来,在双 11 当天有明显的脉冲流量,自动扩缩容保证了这些脉冲流量,同时保证了超时 qps 低于千分之 6(如子图 4)。值得指出的是,2017 年为自动扩缩容运行的第一年,为了保证 11 日当天的成交额,没有将 CPU 水位调到很高,后来微调了集群的 CPU 水位,在所有 P1 水位在 35% 时,还能保证所有 P1 场景降级率均低于 2%。
智能调度系统作为集团双 11 推荐场景的重要基础设施保障,在 2 个月的时间中工程、测试团队联合算法同学完成了从架构设计、算法调试、功能上线测试到双 11 当天百万级的 QPS 的资源调度。从双 11 凌晨 00:15 分接手机器调度开始,智能调度系统在 24 小时中做到了对上层应用开发同学的透明化,保证他们能够投入最大精力冲成交,完全不用担忧资源不够的问题。
智能调度系统全程无需人工干预和拆借机器,完成造势场景,导购场景和购后场景的错峰资源调度,P1 场景资源利用率保持在 30% ,非 P1 资源利用率保持在 50%, 所有 P1 场景降级率低于 2%。即使大促当天各种突发和变动的流量,超时率仍能够控制在千分之六以内,实现了让工程和算法同学 "零点高峰瞪大眼睛认真看,双 11 当天买买买" 的愿望。
感谢桂南、天民、野蔓、永叔对项目的大力支持;
感谢 TPP 各场景的算法同学在智能调度运行过程中提出的宝贵的改进和指导意见;
感谢项目所有参与人员: 剑豪,玉景,巫宸,麒翔,七炎,千鹍,唯勤,林谦,剑持,成都,振之,曲竹,聿剑,画帆,荐轩
原文发布时间为:2017-12-19
来源: https://yq.aliyun.com/articles/293521