查看原文
其他

给 K8s 装上大数据调度引擎:伏羲架构升级 K8s 统一调度

冯亦挥 阿里巴巴中间件 2022-03-18


01

引言

Aliware

基于 K8s 的统一调度是阿里集团的核心项目,随着2021年双十一落下帷幕,这个历时一年多,汇集了蚂蚁、电商、搜索、计算平台等几大调度团队的联合项目在生产场景得到了终极验证。

作为统一调度项目的核心团队,伏羲成功地将 MaxCompute 弹内几万台机器、数百万核计算资源接入了统一调度系统,全程对业务和用户完全无感,无一故障,无一破线,完美实现了“飞行中更换引擎”的目标。统一调度在 MaxCompute 场景的规模化落地,为今年丝般顺滑地支撑双十一洪峰提供了强力保障。通过统一调度项目,伏羲也实现了架构上的再次升级,全面融入 K8s 统一调度架构,让 K8s 生态兼具在线服务和离线大数据的调度能力。

过去几年,阿里技术人一直在探索如何在一个资源池上让不同业务形态的应用在时空上“削峰填谷”,以提升利用率、降低成本、极致资源弹性;另一方面,飞天伏羲在长期的架构演进中,也一直在寻求如何兼容开源生态,更好地为开源引擎提供资源调度服务。基于 K8s 的统一调度,是阿里集团多年混部方案自然演进的结果,也是伏羲拥抱开源的终极形态。本文将从集团混部项目开始谈起,介绍基于 K8s 的统一调度方案,以及 MaxCompute 迁移统一调度的过程。

02

始于混部,终于统一调度

Aliware

阿里集团需要一个庞大的资源系统支撑线上丰富的业务形态,搜索、电商、大数据、数据库等,我们观察到电商纯在线集群长期处于低水位的状态,常态利用率在 10%以下,而以 MaxCompte 为代表的大数据离线集群长期处于高水位,平均利用率 70-80%。

以集团 10 万台(2017 年数字)在线机器为例,通过混部,理论上可以将机器利用率由 10%提升到 45%,这意味着每年可以额外提供 7.8 万台同等计算能力的机器,这是一笔巨大的收益。但混部的挑战也是巨大的,其中最核心的挑战是如何提供一套资源共享机制(全局、单机),在保障各应用 SLA 的前提下,达成集群利用率提升的目标。

01

基于资源静态划分的混部


集团混部项目从 2015 年 9 月正式立项,在经历了初期的技术栈整合和隔离技术的探索后,2017 年正式进入核心生产。当时 0 层作为资源展板,按机器粒度划分在线和离线资源的比例,管理机器的混部角色和状态,而在线离线两个一层调度器基于 0 层分配的资源进行各自业务场景的调度。2017 年双十一,电商和蚂蚁两个混部场景均平稳完成了大促的目标,但也有明显缺点:

1)离线作业的资源使用没有保障,可能被在线应用无条件抢占;
2)在线离线调度器静态划分资源,缺乏灵活性;
3)大促期间,离线全部降级,在更大规模场景下,很难保障离线核心业务的稳定性。

02

混部的进阶:规模化混部


2018 年年初,集团调度系统要全面提升混部能力,将电商混部扩大到万台规模,并全力保障离线作业的运行质量。为此,混部项目提出了资源优先级的概念,通过资源优先级划分,使离线的高优先级作业(Latency Critical)与在线应用在资源保障上处于同等位置,其运行时的稳定性也得到了保障,而离线的普通作业(Best Effort)则继续起着“削峰填谷”,提升集群利用率的作用。为了加强资源管控,原有的 0 层功能也得到了增强:

1)记录在离线两个调度器资源使用情况的资源“账本”,并在资源冲突时进行仲裁
2)接受一层调度器的资源请求,并保证“账本”上的资源信息与单机的资源配置保持一致。

03

基于 K8s 的统一调度


混部项目希望在一个资源池上让不同业务形态的应用在时空上充分“削峰填谷”,从而提升资源利用率,而 0 层作为辅助模块,协同了两个一层调度器的资源使用。但毕竟是两个调度器,由于彼此间无法高效地交互细粒度信息,阻碍了混部效果的进一步提升。如果基于一套调度系统,不仅可以简化部署运维流程,还可以构建统一的资源视图,在相同的资源协议下,通过动态感知各应用运行时的特性,使调度效果逼近全局最优,最终实现资源利用率提升的目标。

Kubernetes(简称 K8s)作为容器应用集群化管理系统,为容器化应用提供了自动化的资源调度,容器部署,动态扩容、滚动升级、负载均衡,服务发现等功能,已成为了容器编排的事实标准,因此基于 K8s 的统一调度自然成为了混部系统下一阶段演进的方向。

1、核心挑战


但 K8s 本身的调度器具有功能和性能上的缺陷:
  • 以 APIServer 为中心的消息同步机制(List-Watch),更适用于调度频度较低的在线服务场景,对于以 MaxCompute 为代表的大数据计算场景(每秒 10 万次的调度频度),无法提供极致的性能保障;
  • 默认的调度器无法提供灵活的多租户队列管理功能;
  • 默认的调度器采取的是静态资源配额管理,不能做到“削峰填谷”,不利于实现集群资源的高利用率;
  • Scheduler 整体上是中心式调度,扩展空间有限,缺乏分布式协同调度能力。

伏羲与 K8s 关键指标比较

为了解决上述问题,需要让 K8s 具备伏羲在规模和性能上的能力,而如何降低 API Server 在高并发场景下的压力成了关键,我们采取了以下方案:
1)将调度相关的信息拆解成资源、执行和状态三部分,非关键信息不落盘;
2)批量更新,减少更新频次。在统一调度架构设计上,我们遵循了以下原则:
  • 新增组件和功能尽量以插件的形式,减少对 K8s 体系的破坏
  • 支持在线离线多种业务形态的混部,在保留 K8s 原生 Pod 语义的同时,针对离线高频调度的特性,扩展了 task 链路协议。既做到了调度上统一,也同时兼顾了在线离线运行时不同的特点。
  • 设计上支持 sharding 作为所有 master 的后续规模扩展手段


2、统一的调度算法和流程



如何通过一个调度器,满足集团多个场景不同业务形态的调度需求,这是设计上的最大挑战。历时 2 个多月,项目组分别从资源账本、调度流程、队列管理、资源协议等维度进行了抽象设计,同时我们也充分参考了 K8s 社区 scheduler framework 插件化机制,通过灵活的调度框架让不同的调度团队可以定制各自的调度需求。


3、统一的资源分类和作业优先级


在资源池的分类上,我们将资源分成了 Prod/Batch/BE 三大类,统一了不同业务部门资源使用的预算口径,而 Batch/BE 资源的定义,则为集群利用率的提升提供了理论依据。在资源分类的基础上,我们进一步将作业优先级在全局打通(蚂蚁、电商、搜索、计算平台),原则上 Prod 的优先级>Batch 的优先级>BE 的优先级,其中 Prod 优先级对应[9000-9999],Batch 优先级对应[6000-6999],BE 优先级对应[3000, 3999]。统一的作业优先级,为混部场景下不同业务形态应用 SLA 的保障提供了参考依据。


4、统一的多租 Quota 机制


不同部门的资源配额如何管理,这是 Quota 管控系统要解决的问题。我们提供了任意多层的 Quota Tree 机制,能同时兼容集团几大业务场景的需求,例如在 MaxCompute 场景下支持任意层 Quota 架构,其中只有叶子节点挂具体的作业,非叶子节点用于圈定一批 QuotaGroup 统一管理和调配(管理者称为接口人)。每个 QuotaGroup 有 MinQuota 和 MaxQuota,MinQuota 是 Guaranteed,MaxQuota 则是业务可申请的资源的上限(可以类比 Kubernetes Pod 的 requests 和 limits)。


多租 Quota 机制除了要保证不同租户间资源使用的公平性,还有一个重要的功能是提供资源弹性能力,即当用户的请求处在波谷时,其 Quota 也能被其他用户共享。我们参照了灌水模型来实现租户间资源的动态弹性,通过“削峰填谷”机制让不同用户充分共享集群资源,最大化集群资源利用率。


如果说集团各大调度平台像几辆并驾齐驱的跑车,统一调度的目标则是给它们找到一个共同的底盘,在调度算法流程、资源分类和作业优先级、多租 Quota 机制等调度基础设施上给出了统一的定义,同时为不同业务场景的调度需求保持了一定的灵活性,一个松紧有度的调度框架也为后续各业务线应用的迁移创造了条件。

03

MaxCompute 迁移统一调度

Aliware

伏羲作为阿里云计算平台的核心底座,通过 MaxCompute,支撑了阿里集团海量大数据计算需求,目前已管理了超过十万规模的计算节点,平均每天调度千万级别的作业,在几百万核的计算单元上运行几十亿级别的 worker,处理 EB 级别的数据。将 MaxCompute 业务从伏羲迁移到统一调度是一个浩大的工程,一方面线上业务正在跑,调度特性不能有丝毫的回退,我们必须在极短的时间内把过去十多年大数据的调度能力重新长在统一调度上;另一方面,为了不降低平台体验,迁移过程要做到对用户透明,需要对系统的调用链路做细致的梳理,前期的方案设计和后期的步骤实施都要做到谨小慎微,非常考验我们的工程能力。


01

也要性能极致


通常在线应用是启动一次,长时间运行,因此 Kubernetes 的调度器在并发和性能上的表现并不出色, 而以 MaxCompute 为代表的大数据计算场景,每秒就有成千上万次资源在流转,对调度器的性能有着极高的要求。如何在大数据计算高并发场景下,让调度性能做到极致,这是统一调度项目的最核心的挑战。

1、task 链路通信协议优化


大数据场景资源的高频流转会在 API Server 侧产生极大的压力,导致整体调度性能随着规模的扩大而迅速衰减。

通过进一步性能分析,我们发现 API Server 有如下假设:
1)数据到达的顺序要和推送到 watch 的顺序全局严格一致;
2)数据同步落盘后才能开始向 watch 推送。由于 Task(task 链路的资源对象)的局部特性,只会被一个 TaskGroup(一个调度单元,相当于 pod)订阅,因此我们对 task 链路的通信协议进行了以下改进:以去中心化(peer to peer)方式直接在角色间进行通信,并将其封装成了 tasklib,支持标准的 K8s list/watch 机制。在相同的压力场景下,无论是 e2e 的效果还是稳定性都有了明显的改善,基本解决了大规模高并发场景下通信链路瓶颈的问题。

2、task 链路调度性能优化


资源调度是将请求和资源相互匹配的过程,常见做法是将请求从队列中取出,然后经过 Filter/Score 等插件依次进行过滤打分,选出合适的机器后进行分配,这是请求查找资源的过程。对于压力较小、调度延时不太敏感的在线调度场景,上述方式通常能给出局部最优解;但对于大数据计算场景,由于作业本身的短时特性,需要调度延时尽量小,通过资源的高速流转使集群保持高吞吐率,当机器资源释放出来后,需要快速地查找能够使用这批资源的请求,这是资源查找请求的过程。针对离线场景的这种调度需求,我们在在线 BestFit 流程的基础上,引入了 FirstFit 流程:

  • 当 UniRequest 初次进入调度系统,在执行完请求查找资源的逻辑后,如果仍未满足,则将请求插入到 Mach->UniRequest 的 Queue 中,Queue 按 Quota 组聚合(Quota 组内有序)
  • 当机器有资源变化时,触发 Mach->UniRequest 流程,从某个 Quota 组队列中查找合适的 UniRequest(在寻找过程中执行 Filter 逻辑)
  • 同一台机器同一时刻只触发一个 Queue 的调度,同一个 Queue 同一时刻只能被一台机器触发调度

由于是按机器粒度触发调度,上述方式天然不存在资源冲突,可以全速并发执行。另外,我们还通过树结构加速了请求与多维资源匹配的过程,虽然也存在无效遍历导致的回溯,但整体表现依然十分出色。

02

飞行中更换引擎


统一调度从设计第一天就考虑了各个业务方如何进行系统升级,参考之前系统架构升级的经验,我们对本次统一调度系统升级的要求也非常明确,即平滑热升级,全程对用户透明无感。但在 MaxCompute 技术体系中,伏羲一方面是分布式系统的资源管理和调度的组件,需要与上层作业执行引擎(AppMaster)进行资源交互,另一方面也是各种运维管控(比如大数据运维平台 Tesla)的数据源,复杂的模块依赖决定了系统升级是一件非常艰巨的事情,如果将 MaxCompute 比作一架高速飞行的飞机,统一调度升级就是要给这架飞行中的飞机更换引擎,难度可想而知。为此,我们对资源交互协议进行了适配改造,并专门开发了一套热升级系统。


1、协议改造


资源交互协议是调度系统中比较繁琐的一个部分,由于架构上的差异,原生伏羲的资源调度协议与统一调度的资源交互协议存在着较大差异,而协议变更需要对上层 AppMaster 业务逻辑透明,为此我们基于 cgo+jni 封装了一套 UnischedulerAppMasterLib 接入层,自动识别本地执行系统是伏羲还是统一调度系统,实现了上层引擎一份代码可以在多套环境无差别运行。

2、热升级系统


与大家熟悉的在线系统不同,离线的升级通常没有 buffer 机器,在这种情况下,如何实现万台规模集群升级到统一调度系统呢?根据 MaxCompute 自身的业务特点,我们从以下两个维度进行了拆分:

1)在资源维度,按机器粒度,逐步将机器从伏羲系统迁移到统一调度系统;
2)在任务维度,按 Quota 组粒度,将作业从伏羲系统迁移到统一调度系统。在迁移过程中,这两个维度的调整要相互配合,以保证当前迁移的作业能在统一调度系统里稳定运行。

统一调度热升级示意图


04

结语

Aliware

在分布式调度领域,Google 用 Borg 实现了一套调度系统支撑多种应用引擎,并通过混部节省了 20%的机器资源,这一直为大家所津津乐道。实现统一调度一方面需要有强大的技术储备作支撑,同时也要考虑各种非技术的因素,比如公司不同发展阶段技术选型带来的历史包袱,多个调度团队分属于不同业务部门的现实因素,这将极大考验公司技术治理的决心。也是因为这些原因,国内的互联网公司大部分还是多个业务部门多套系统并存的局面,无法享受多种应用混部带来的资源红利。

阿里巴巴蚂蚁、电商、搜索、计算平台等多个部门的调度团队在各自领域积累了丰富的调度经验,统一调度是阿里集团几大调度团队的一次技术大会战,让集团的业务跑在一个资源池的一个调度系统上,今天我们初步达成了目标,但这也仅仅是开始。

简单的庆祝之后,也需要冷静地思考随之而来的问题,比如多个团队之间如何协作进行功能开发,如何进行版本管理和控制发布节奏,如何通过有效的测试保证各个场景的 feature 稳定可靠,这将非常考验项目组的集体智慧。但方法总是比问题多,随着时间的推移,相信这些问题都会得到很好的解决。

在统一调度大规模集群成功上线的基础上,下一阶段我们可以尝试在集团范围推进更大规模的混部,进一步压榨集群的资源利用率,收割线上资源的红利。

飞天伏羲作为有着十多年历史的调度团队,在服务好 MaxCompute 大数据平台的过程中,一直在不断通过自我革新赶超业界先进水平,我们经历了 Fuxi 2.0 的这样的大规模升级,今天通过 K8s 统一调度项目又再次实现了系统架构的蜕变,将大数据平台强大的调度能力赋予 K8s 系统,同时去拥抱 K8s 周边丰富的生态。除了集团弹内集群,将来我们在公共云、专有云等多个场景,也会以 K8s 统一调度的方式进行输出,以更好地服务云上的用户,敬请期待!

05

招贤纳士

Aliware

真诚希望与分布式调度领域感兴趣的同学进行深入交流,更期待大家的加入,一起在云端构建世界领先的的计算能力(联系我们:yihui.feng@alibaba-inc.com)。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存