作者|邵伟
编辑|邓艳琴
导读:互联网应用通常以天为单位,尤其在线业务的资源使用情况往往会随着访问数量的波动而变化,具备明显的潮汐特性;为充分实现集群资源的削峰填谷,字节从 2019 年就开始进行在离线混合部署的探索,经过多年持续迭代,最终提炼出了一套 Kubernetes Native 的资源管控系统 Katalyst 并实现正式开源。在 QCon 全球软件开发大会(广州站)2023 中,抖音高级研发工程师邵伟围绕 Katalyst 系统,介绍了字节跳动多年来在大规模业务云原生化场景中资源管理能力的经验和总结,帮助听众梳理资源管理落地实践过程中的核心要点,实现降本增效。本文由此整理。
PPT | https://qcon.infoq.cn/2023/guangzhou/presentation/5287
GitHub:https://github.com/kubewharf/katalyst-core
背 景
字节从 2016 开始着手服务云原生化改造,截至今日字节服务体系主要包含四类:传统微服务大多是基于 Golang 的 RPC Web 服务;推广搜服务是传统 C++ 服务,对性能要求更高;此外还有机器学习和大数据以及各类存储服务。
云原生后需要解决的核心问题是如何提高集群的资源利用效率;以典型的在线服务的资源使用情况为例,深蓝色部分是业务实际使用的资源量,浅蓝色部分为业务提供的安全缓冲区,即使增加缓冲区仍有很多资源处于业务已申请但未使用的状态。因此优化重点是从架构的角度尽可能地利用这些未使用的资源。
1.1 资源治理方案
字节内部尝试过若干不同类型的资源治理方案,包括
所以最终字节采用混合部署将在线和离线同时运行在相同节点,充分利用在线和离线资源之间的互补特性,实现更好的资源利用;最终我们期望达到如下图效果,即二次销售在线未使用的资源,利用离线工作负载能够很好地填补这部分超售资源,实现资源利用效率在全天保持在较高水平。
字节混部发展历程
随着字节云原生化的历程,我们根据不同阶段业务需求和技术特点,选择合适的混合部署方案,并在此过程中不断迭代我们的混部系统。
2.1 阶段一:在离线分时混部
第一个阶段主要进行在线和离线的分时混合部署。
该方案优势在于不需要采取复杂的单机侧隔离机制,技术实现难度较低;但同样存在一些问题,例如
2.2 阶段二:Kubernetes/YARN 联合混部
为解决上述问题我们进入了第二个阶段,尝试将离线和在线真正跑在一台节点上。
由于在线部分早先已经基于 Kubernetes 进行了原生化改造,但大多数离线作业仍然基于 Yarn 进行运行。为推进混合部署,我们在单机上引入第三方组件负责确定协调给在线和离线的资源量,并与 Kubelet 或 NodeManager 等单机组件打通;同时当在线和离线工作负载调度到节点上后,也由该协调组件异步更新这两种工作负载的资源分配。
该方案使得我们完成混部能力的储备积累,并验证可行性,但仍然存在一些问题
2.3 阶段三:在离线统一调度混部
为解决第二阶段的问题,在第三阶段我们彻底实现了在离线统一的混合部署。
通过对离线作业进行云原生化改造,我们使它们可以在同一个基础设施上进行调度和资源管理。该体系中,最上面是统一的资源联邦实现多集群资源管理,单集群中有中心的统一调度器和单机的统一资源管理器,它们协同工作,实现在离线一体化资源管理能力。
在该架构中,Katalyst 作为其中核心的资源管控层,负责实现单机侧实时的资源分配和预估,具有以下特点
Katalyst 系统介绍
Katalyst 引申自英文单词 catalyst,本意为催化剂,首字母修改为 K,寓意该系统能够为所有运行在 Kubernetes 体系中的负载提供更加强劲的自动化资源管理能力。
3.1 Katalyst 系统概览
Katalyst 系统大致分为四层,从上到下依次包括
3.2 抽象标准化:QoS Class
Katalyst QoS 可以从宏观和微观两个视角进行解读
在 QoS 的基础上,Katalyst 同时也提供了丰富的扩展 Enhancement 来表达除 CPU 核心外其他的资源需求
3.3 管控同步化:QoS Resource Manager
为在 K8s 体系下实现同步管控的能力,我们有三种 hook 方式:CRI 层插、OCI 层、Kubelet 层;最终 Katalyst 选择在 Kubelet 侧实现管控,即实现和原生的 Device Manager 同层级的 QoS Resource Manager,该方案的优势包括
3.4 策略智能化:服务画像和资源预估
通常,选择使用业务指标构建服务画像比较直观,例如服务 P99 延迟或者下游的错误率。但其也存在一些问题,比如相对系统指标而言,业务指标的获取通常更不容易;业务通常会集成多个的框架,他们生产的业务指标含义并不完全相同,如果强依赖这些指标,整个管控的实现就会变得非常复杂。
因此,我们希望最终的资源调控或服务画像是基于系统指标而非业务指标来实现;其中最关键的就是如何找到业务最关心的系统指标,我们的做法是使用一套离线的 pipeline 去发现业务指标和系统指标之间的匹配。例如,对于图中服务来说,最核心的业务指标是 P99 延迟,通过分析发现与其相关度最高的系统指标是 CPU 调度延迟,我们会不断调整服务的资源供应量,尽可能地逼近它的目标 CPU 调度延迟。
在服务画像的基础上,Katalyst 针对 CPU、内存、磁盘和网络等方面提供了丰富的隔离机制,必要时还对内核进行了定制以提供更强的性能要求;然而对于不同的业务场景和类型,这些手段并不一定适用,因此需要强调的是隔离更多是一种手段而不是目的,我们在承接业务的过程中需要根据具体的需求和场景来选择不同的隔离方案。
3.5 运维自动化:多维度动态配置管理
尽管我们希望所有的资源都在一个资源池系统下,但是对于在大规模生产环境中,不可能把所有节点都放在一个集群里;此外,一个集群中可能同时有 CPU 与 GPU 的机器,虽然可以共享控制面,但在数据面上需要一定的隔离;在节点级别,我们也经常需要修改节点维度配置以进行灰度验证,导致在同一节点上运行的不同服务的 SLO 存在差异。
为解决这些问题,我们需要在业务部署时,考虑节点的不同配置对服务的影响。为此,Katalyst 针对标准交付提供了动态配置管理的能力,通过自动化的方法评估不同节点的性能和配置,并根据这些结果来选择最适合该服务的节点。
Katalyst 混部应用与案例分析
在该部分我们将结合字节内部的案列分享一些最佳的实践。
4.1 利用率效果
从 Katalyst 实施效果上来说,基于字节内部业务的实践,我们在季度周期内,资源都可以保持在相对较高的状态;在单个集群中,每天的各个时间段内资源利用率也呈现出比较稳定的分布;同时,集群中大部分机器利用率也比较集中,我们的混合部署系统在所有节点上运行都比较稳定。
点击图片可查看完整电子表格
4.2 实践:离线无感接入
在进入第三阶段后,我们需要对离线进行云原生化改造。改造方式主要有两种,一种是已经在 K8s 体系中的服务,我们将基于 Virtual Kubelet 的方式实现资源池的直接打通;另外一种 YARN 架构下的服务,如果使用对进行彻底的改动,则对于业务来说成本非常高,理论上会导致所有业务都滚动升级,这显然不是一个理想的状态。
为了解决这个问题,字节引用 Yodel 的胶水层,即业务接入仍然使用标准的 Yarn API;但在这个胶水层中,我们将与底层 K8s 语义对接,将用户对资源的请求抽象为像 Pod 或容器的描述。这种方法使得我们在底层使用更成熟的 K8s 技术来管理资源,实现对离线的云原生化改造,同时又保证了业务的稳定性。
4.3 实践:资源运营治理
在混部过程中,我们需要对大数据和训练框架进行适配改造,做好各种重试、checkpoint 和分级,才能确保在我们将这些大数据和训练作业切到整个混部资源池之后,它们的使用体验不至于太差。
同时,在系统上我们需要具备完善的资源商品、业务分级、运营治理以及配额管理等方面的基础能力。如果运营做得不好,可能使得在某些高峰时段将利用率拉得很高,但在其他时段可能会出现较大的资源缺口,从而导致利用率无法达到预期。
4.4 实践:极限资源效率提升
在构建服务画像时我们采用的是即基于系统指标去做管控,但基于离线分析得到的静态系统指标无法实时跟上业务侧的变化,需要在一定时间周期内分析业务性能的表和性能变化来调整静态值。
为此,Katalyst 引入了模型来微调系统指标。例如,如果我们认为 CPU 调度延迟可能是 x 毫秒,过一段时间后,通过模型算出业务目标延迟可能是 y 毫秒,我们就可以动态地调整该目标的值,以更好地评估业务性能。
以下图为例,完全使用静态的系统目标来进行调控,业务 P99 将处于剧烈波动状态,这意味着在非晚高峰时段,我们无法将业务资源使用压榨到更极致的状态,使其更接近业务在晚高峰时可承受的量;引入模型后,可以看到业务延迟会更加平稳,使得我们可以全天将业务的性能拉平到一个相对平稳的水平,获得资源的收益。
4.5 实践:解决单机问题
在混部推进的过程中,我们晦不断遇到在线和离线各种性能问题和微拓扑管理的诉求。例如,最初所有机器都是基于 cgroup V1 进行管控,然而由于 V1 的结构会使得系统需要遍历很深的目录树,消耗大量 内核态 CPU,为了解决该问题,我们在将整个集群中的节点切换到 cgroup V2 架构,使得我们能够更加高效地进行资源隔离和监控;对于推广搜等服务服务来说,为追求更加极致的性能,我们需要在 Socket/NUMA 级别实现更加复杂的亲和与反亲和策略等等,这些更加高阶的资源管理需求,在 Katalyst 中都可以更好地实现。
总结展望
Katalyst 已正式开源并发布 v0.3.0 版本,后续将会持续投入更多精力进行迭代;社区将在资源隔离、流量画像、调度策略、弹性策略、异构设备管理等多方面进行能力建设和系统增强,欢迎大家关注、参与该项目并提供反馈意见。
GitHub:https://github.com/kubewharf/katalyst-core