1.2 集群任务调度
在一个大的资源池中,一般都会运行多种Workload,有的是离线任务,有的是在线任务。这些任务都需要至少1~N组透明的、隔离的、完整的资源,其表现形式如虚拟机、容器、K8s(Kubernetes的简写)的Pod或者Linux Cgroup。在一个机房或者物理集群中,物理资源总是有限的,或者说稀缺资源总是有限的。那么,当多个任务或者多个资源需求到达集群调度时,就会面对任务调度的一般策略,在特殊情况下,什么样的任务可以被优先调度呢?
1.2.1 问题背景
当多个任务或者多个资源需求到达集群调度时,如何进行资源需求的调度呢?也就是说,谁最先从申请队列中出队,出队后的资源申请将获得调度分配的资源。比如现实生活中的一个场景:排队等公交车,先上车后选座位。“排队上车”这个过程就是任务调度的过程。排队上车采用的是FIFO(First In First Out)策略,在实际资源申请的场景中,是存在多种策略的。
1.2.2 解决什么问题
集群任务调度解决什么问题呢?用一句话描述,就是:当多个资源需求到达集群调度时,如何确定哪个资源需求被选择进入调度器进行资源分配。具体需要解决的问题如下。
具体问题1:采用一般的排队策略,如FIFO、FAIR(Fair Scheduler)等。
应用场景:当有N个资源需求到达时,按照区域或者用户特征等进行队列路由,不同的队列对应于一组资源池(逻辑上的资源划分),按照FIFO策略调度。当资源池特别大时,FIFO策略对用户是无感的。当资源有限或者资源稀缺时,将不再采用FIFO策略,而是结合需求等级来定,一般高等级的需求被优先调度。如果说对资源的占用是短时间的,那么总体来看,最终所有任务的机会是均等的。但是,占用时间的不同,会加剧对稀缺资源的竞争。因为资源一旦被其他任务占用,就意味着在一段时间内,自己将没有机会获取到资源。
具体问题2:采用抢占策略,如权重、预留、预约等。
应用场景:总是有突发的需求、紧急的需求、个性化的需求,那么在有限的资源池中,如何从技术上支持,并且做到可管理、可控地交付呢?也许很难准确地给出需求量、需要的时间点,但是通过预留、预约可以做到部分事前准备。
1.2.3 一般解法
在讨论解法前,首先需要有一个取舍标准——指导如何设计权重、如何预留、如何兼顾公平。一个普遍性准则是:资源利用率优先。也就是说,给需求设置权重,优先考虑资源利用率画像数据、资源需求的规模、资源池供应的能力。还有一个准则是:收益最大化。这里对收益的度量非常关键,站在不同的维度看收益,比如从业务价值看、从业务资源投入成本看、从资源平台分时复用能力看,会导向不同的技术实现。
经验表明,当资源池足够大时,FIFO是最简单、有效的任务调度策略;而当资源池容量有限或者资源池剩余资源有限时,FIFO策略会导致“饥饿”。例如,小规格资源申请,会导致资源碎片化,当大规格资源申请到达时分配不出来资源。比如,对于IP资源,大量的非重要资源申请,占用了大量的网络IP地址,当关键任务需要网络IP地址资源时,资源不够用将严重影响资源的交付。例如,在电商促销期间,各种应用都开始扩容,此时FIFO策略将导致各业务“提前”申请资源或者“抢购”资源。
● 权重(Weight):引入权重,就意味着差别对待。这种差别有时候会间接影响业务交付进度。一般权重的维度包括业务等级、资源利用率、业务可迁移性[2]、业务资损[3]。
● 预约(Booking):对需求的一种管理,是针对相对明确的未来需求提出的一种解决方案。当预约这种协议如期到达时,这类任务会被强调度、强交付。
● 预留(Reserved):对资源的一种管理,是针对未来一定发生的需求所需要资源提出的一种解决策略。对稀缺资源或者紧急资源的预留比较常见。另外,还有Buffer池的预留,其主要用于应对软硬件故障、主动运维任务。这类任务通常是后台任务,优先级最高。
● Fair策略(FAIR):即平均分配,也就是公平优先。一方面是任务数的公平;另一方面是资源诉求量的公平。● 批量处理(Batch):在吞吐量比较突出的场景中,批量可以提升处理的规模。
在实践过程中,简单、稳定优先,例如FIFO + Batch可能就解决了80%的场景需求,剩余20%的场景需求,可能需要80%的精力逐步支持权重、预约;而预留是必不可少的。
1.2.4 实践案例
阿里巴巴交易促销活动会联动多个业务场景,在每个场景下有多个应用、多地域的服务器资源扩容服务。整个资源任务的过程抽象为:(大的业务节点)云资源预约、云资源交付、云资源释放。其中云资源交付包括资源需求收集(一般在预约之前)、资源需求等级划分、离线编排、资源预留、批量申请、FIFO申请等关键过程,如图1-5所示。
图1-5 阿里巴巴交易促销任务过程