根据 Gartner 预测数据显示:2024 年全球 IT 支出预计将达到 5.1 万亿美元,比 2023 年增长 8 %。然而,该机构的另一项调查数据显示:全球数据中心服务器平均 CPU 利用率普遍低于 20%,存在巨大的资源浪费。据测算,以数百万核 CPU 规模的数据中心为例,每提升 1 个百分点的整体资源利用率,每年将节省数千万元的成本。由此可见,提高资源利用率对于降低企业运营成本具有显著的效果。
早在 2015 年,谷歌就在其经典论文《Large-scale cluster management at Google with Borg》中披露了它在资源管理和调度方面的实践经验,是最早通过混部技术来提升资源利用率的公司之一。国内多家头部互联网企业也相继实施类似的技术方案,并取得可观的资源利用率提升效果。
随着小红书业务的高速发展,各类在线、离线业务对计算资源的需求日益增长。与此同时,我们观察到:部分在线集群天均利用率的水位却维持在较低的水平。造成这一现象的主要原因有以下几点:
- 在线服务资源使用量随着终端用户的使用习惯呈现稳定的潮汐现象,夜间 CPU 利用率极低,从而导致整个集群的均值 CPU 利用率降低。
- 业务保有大量的独占资源池,资源池割裂产生大量的资源碎片,进而降低 CPU 的利用率。
- 出于稳定性考虑,业务倾向于过量储备资源,进一步降低 CPU 的利用率。
基于以上背景,为了帮助业务降低资源使用成本,小红书容器团队从 2022 年开始规模化落地混部技术,提升集群 CPU 利用率。截止目前,混部集群 CPU 利用率均值可达 45% 以上,为业务提供数百万核时的算力成本优化。
1、技术演进
小红书混部技术演进分为以下四个阶段(如图所示):
阶段一:闲置资源再利用
在早期,小红书的集群资源管理相对粗放,集群中存在大量业务独占的资源池。由于资源碎片化等因素,各个集群中存在许多低分配率的低效节点,导致大量资源浪费。同时,基于 Kubernetes(K8s)发布的转码类近线/离线场景,在全天时段均存在大量计算资源需求。基于以上背景,小红书容器平台通过技术手段将集群中的闲置资源进行收集,并将其分配给转码类业务场景使用。
整体架构上,离线业务发布入口统一收敛在在一个集群,我们称之为元数据集群,目的是为业务屏蔽底层多物理 K8s 集群。通过 Virtual-Kubelet 连接元数据集群与物理集群,将闲置资源汇聚到元数据集群,在元数据集群中调度分发转码类任务到底层物理集群。
策略方面,二次调度器负责巡检集群中的所有节点,识别出低效节点并进行标记;随后 Virtual-Kubelet 获取物理集群中的低效节点可用资源作为集群闲置资源,再次分配给离线转码场景。同时,二次调度器确保一旦在线服务有资源需求,将会立刻驱逐离线 Pod 并归还资源。通过此举,我们能够提高集群资源的利用效率,减少资源浪费,并满足转码类场景对计算资源的需求。
阶段二:整机腾挪分时复用
搜推广等业务的独占资源池,存在明显的 CPU 利用率潮汐现象,尤其夜间利用率极低。通常情况下,资源池中的单个节点往往也只部署一个大规格业务 Pod。基于这种情况,平台通过弹性能力(HPA),在凌晨业务低峰期按比例对在线业务进行缩容,释放出整机资源,并将转码、训练等离线 Pod 在该时段运行起来,实现资源优化,起到利用率“填谷”的效果。
在具体实施过程中,我们需要确保在线服务能够在规定的时间内全部被拉起。为此,我们采取以下策略:实现离线服务的提前退场,并通过调度器的抢占机制进行兜底,确保在线服务在业务高峰期来临之前能被全量且及时地重新启动。
这一阶段能最大限度地利用资源,使得离线服务在低峰期得到有效运行,同时保证在线服务在业务高峰期能够快速恢复运行。
阶段三:常态混部
为了降低资源碎片率和业务资源持有成本,平台持续推进业务的大规模合池,将业务从独占资源池迁移到平台托管的公共混部池。通过合池、资源超卖等技术手段,我们有效提升了 CPU 分配率,但依旧无法解决合并后的资源池夜间利用率较低等问题。另外,在合池后的复杂混部场景下,整机腾挪、分时混部离线的调度策略很难再继续实施。平台需要建设更为细粒度的资源管理与调度能力,来实现均值利用率提升的目标,具体包含以下几点:
1. 调度侧
- 通过动态超卖技术获取可用于二次分配给离线服务的可用资源量,并抽象出离线资源视图,使得 K8s 调度器感知到这些离线资源。调度器调度离线负载到对应节点上,实现离线服务对节点利用率的“填谷”效果。
- 通过负载调度,尽可能避免在线服务被调度到高负载机器上,让集群中节点负载更加均衡。
- 通过二次调度,驱逐负载热点机器上的高利用率服务,使得集群负载保持动态均衡状态。
2. 单机侧
- 支持 QoS(Quality of Service)保障策略,根据服务的 QoS 等级提供差异化的运行时资源保障能力。
- 支持干扰检测、离线驱逐等能力,当离线服务对在线敏感服务产生干扰时,第一时间驱逐离线服务。
- 通过以上技术手段,我们能够有效地保障服务混合部署时的稳定性,从而实现在线和离线工作负载在节点上的常态混合运行,实现利用率“填谷”效果的最大化。
阶段四:统一调度
随着常态混部和大规模资源合池的持续推进,小红书云原生资源调度将会面临以下挑战:
1. 各类业务场景对资源调度存在复杂且各异的功能和性能需求
- 大数据、AI 场景下:排队调度、批量调度(All-or-Nothing)、高吞吐量调度等需求。
- 在线敏感服务场景下:资源调度成功率保障性需求、服务运行时质量保障性需求。
2. GPU 等异构资源调度需求
- 支持 GPU 共享调度、bin packing等调度能力,以提升 GPU 利用率及 GPU 机器上的 CPU 利用率。
- 支持 GPU 拓扑感知、亲和性调度等调度能力,通过优化 GPU 间的通信效率,大幅提升大规模训练效率。
基于以上背景,我们提出面向混合云架构的统一调度方案。该方案基于统一资源池,通过统一调度能力来管理异构计算资源,并支持各类业务形态的工作负载调度能力。通过站在全局视角,将工作负载调度到最合适的节点,让业务跑得更快更稳定,并降低全局资源使用成本。涉及到的关键技术点如下:
1. 在离线统一调度
提供以 K8s 为底座的统一调度能力,支持包含在线敏感型服务、大数据/ AI 任务型工作负载在内的统一资源调度。
2. QoS 感知调度
基于服务画像,结合系统指标识别干扰源,并刻画节点资源质量。通过综合调度、重调度和单机调度等不同维度的调度能力,降低业务间混部造成的干扰,从而提升在线服务的运行质量。
3. GPU 调度
支持 GPU Share、bin packing、多 GPU 卡之间的亲和性调度等调度能力,以提高 GPU 资源的利用效率。
4. 资源售卖模型
根据资源质量、资源供应形态(如常态化供应资源、分时潮汐资源、Spot 资源)和资源套餐规格等多个维度,定义差异化资源售卖模型,降低资源综合使用成本。
5. 资源配额
支持资源配额管理能力,包括分时配额、弹性配额和层级结构管理等功能,避免多租户之间的资源争抢,提升资源使用效率。
2、架构设计与实现
小红书容器统一资源调度系统 Tusker (The Unified Scheduling system base on Kubernetes for Efficiency and Reliability) 架构设计如图所示:
小红书的各类业务场景通过多个发布平台和任务平台提交,并通过上层负载编排能力,以 Pod 形式下发到统一调度系统。统一调度系统基于不同的调度需求,为在线服务提供强保障的资源交付能力、差异化的 QoS 保障能力,同时为离线服务提供最小资源需求的保障能力和极致的弹性能力。
在调度侧,离线调度采用 Coscheduling 技术;二次调度处理资源热点问题,包括热点驱逐和碎片整理;负载调度基于 CPU 水位进行调度,以实现更好地资源利用;资源视图用于资源走查和模拟调度。
在单机侧,通过压制策略如 BVT(Borrowed Virtual Time)进行性能控制和资源限制,并进行内存驱逐操作;QoS 保障方面,采用绑核和超线程干扰抑制等技术来实现资源的差异化保障;计算和上报可用的 Batch 资源信息;来自 Kernel 的指标采集包括 PSI(Pressure Stall Information)、调度信息等;干扰检测基于 CPI(Cycles Per lnstruction)、PSI(Pressure Stall Information)和业务指标等,用于检测和处理干扰情况。
2.1 离线调度资源视图
离线服务资源调度的基本原理是基于在线服务负载感知能力的动态超卖,具体实现是将节点空闲资源二次分配给离线业务:
其中离线可用资源为节点上的空闲资源(包含未分配资源和已分配未使用资源之和),扣除安全预留资源之后的剩余资源,离线可用资源计算公式如下:
离线可用资源 = 整机资源 – 预留资源 – 在线服务实际使用量
将计算出的离线可用资源量按照时间分布后如图所示(图中绿色部分):
实际落地过程中,为了避免离线可用资源随在线服务资源使用波动而大幅波动,从而影响离线资源质量和离线服务运行稳定性,可以通过资源画像对上述公式中的在线服务实际使用量数据进一步处理,去除数据噪点,最终计算出一个相对稳定的离线可用资源量(图中绿色部分),如图所示:
2.2 混部 QoS 保障策略
2.2.1 QoS 分级
按照业务对于服务质量(QoS: Quality of Service)的需求,小红书的业务类型可以简单划分为三个 QoS 级别,如下表所示:
QoS 等级 | 说明 | 业务场景 |
Latency-Sensitive | 最高 QoS 保障等级,延迟极为敏感服务 | 搜推广延迟极为敏感场景 |
Mid | 默认 QoS 保障等级,容忍部分干扰延迟 | 网关、Java 微服务 |
Batch | 最低 QoS 保障等级,延迟不敏感,资源随时可能被抢 | 转码、Spark、Flink、训练等计算场景 |
2.2.2 QoS 保障
根据服务的 QoS 需求,节点侧可以采取 Pod 粒度的分级资源保障,以实现不同资源维度的差异化 QoS 保障策略,具体的保障参数如下:
资源 | 特性 | Latency-Sensitive | Mid | Batch |
CPU | CPU Burst | enable | enable | disable |
调度优先级 | 最高 | 默认 | 低 | |
绑核 | share (默认) | share(默认) | reclaimed | |
NUMA | 强保证 | prefer(默认) | none | |
L3 Cache | 100% | 100%(默认) | 30% (默认) | |
内存带宽 | 100% | 100%(默认) | 30% (默认) | |
内存 | OOM 优先级 | 最低 | 默认 | 最高 |
内存回收水线 | 调高 | 默认 | 调低 |
在 CPU 核编排层面,我们针对不同的需求场景,设置了三种不同的绑核类型,并设计了一套精细化 CPU 核编排策略,分配示意图如下:
三种绑核类型分别为:
Exclusive
特点:绑定 cpuset 调度域、CCD 感知、NUMA 绑定、独占排他
场景:适用于对延迟极为敏感的搜推广大规格服务
Share(推荐)
特点:绑定 cpuset 调度域、CCD 感知、NUMA(可选)绑定、Share/Exlusive 排他、可与 None 类型业务共享
场景:适用于容忍部分干扰的 Java 微服务、应用网关、Web服务等
Reclaimed
特点:无 cpuset 绑定、可能与非 exlusive 绑核模式的业务共享核,核的分配完全由内核控制,CPU 资源并非百分之百能够满足需求
场景:适用于 Batch 类离线服务,部分对延迟无要求的计算服务
2.2.3 离线驱逐
在极端场景下,如整机内存使用率较高、有触发 OOM 风险,或者离线业务 CPU 长期得不到满足时,可以采取离线驱逐策略。单机侧支持按照离线服务内部定义的优先级配置、资源用量和运行时长等多维度综合算分排序后,按序驱逐离线服务,以达到最优的资源利用效果。
2.3 离线业务场景举例
小红书作为一个拥有数亿用户的内容社区,其离线业务场景丰富多样,其中包含大量视频类和图片类转码场景、搜推、CV/NLP 算法推理训练、算法特征生产以及数仓查询等离线场景。具体而言,包含以下业务类型:
- 近离线转码场景(已容器化)
- Flink 流式/批式计算(已容器化)
- Spark 批式计算 (未容器化、On YARN)
- CV/NLP 算法回扫场景(已容器化)
- 训练场景 (已容器化)
通过基于 K8s 的在离线统一调度能力,将这些离线业务与在线服务混合部署在统一资源池中。不仅能为在线服务提供差异化的资源质量保障,亦能为离线服务提供海量的低成本算力,以实现资源效能的提升。
2.3.1 K8s 与 YARN 混部方案
在小红书商业化、社区搜索等业务中存在大量的算法类 Spark 任务,由于离线集群资源紧张,任务无法及时处理,导致任务堆积。同时,在线集群在业务低峰时段资源使用率较低。另外,相当大比例的 Spark 任务资源调度仍运行在 YARN 调度器上。基于此背景,为了快速降低业务迁移成本,在方案选型方面,我们选择与 Kooridinator 社区合作,采用 YARN on K8s 混部方案来快速落地 Spark 离线场景混部,具体方案如图所示:
在线和离线工作负载在容器化环境下通过 K8s 链路发布到在线集群内。Spark 作业通过 YARN ResourceManager 调度到具体节点,并由节点上的 NodeManager 组件拉起。NodeManager 以容器的形式部署在在线 K8s 集群中,实现资源的有效管理。除此之外,还涉及到以下组件:
1. 调度侧
Koord-Yarn-Operator:支持 K8s 与 YARN 调度器资源视图的双向同步,确保资源信息的共享和一致性。
2. 节点侧
Copilot:作为 NodeManager 的操作代理,提供 YARN Task 的管控接口。
Tusker-agent/koordlet:负责离线资源的上报、节点上离线 Pod/Task 管理,并处理冲突解决、驱逐、压制策略等功能。
多调度器资源同步
K8s 调度器与 YARN 调度器之间原本独立且相互不感知,为了共享分配节点上的总可用离线资源,需要通过 Koord-Yarn-Operator 组件来做两个调度器之间的资源双向同步和协调,并实现两个同步链路:
1. K8s ->YARN 调度器资源同步链路,负责同步 YARN 视角离线资源总量,其中 YARN 离线资源总量计算如下:
YARN离线资源总量 = 离线总可用量 – K8s 侧节点已分配
2. YARN->K8s 调度器资源同步链路,负责同步已分配的 YARN 资源量,其中 K8s 离线资源总量计算如下:
K8s 离线资源总量 = 离线总可用量 – YARN 侧节点已分配
基于各自节点离线资源视图,两个调度器分别作出调度决策,将离线 Pod 与 YARN Task 调度到适当的节点上。由于同步过程不适合加锁,可能会出现资源被过量分配的问题:
具体解决措施是在单机侧增加了仲裁逻辑。当节点已分配的离线服务资源量长期超过节点可用离线资源,且离线使用率持续较高时,存在离线服务无法获得资源而被饿死的风险。单机侧会根据离线服务的优先级、资源占用量和运行时长等因素综合算分,并按序驱逐。
3、落地收益
截止目前,小红书混部能力覆盖数十万台机器规模,覆盖算力规模数百万核,支持数万规模在线、离线场景服务的资源调度。通过大规模容器混部的持续推进,小红书在资源成本效能等方面都取得了显著收益,具体包含以下两方面:
CPU 利用率
- 在保证在线服务服务质量的前提下,在线混部集群天均 CPU 利用率提升至 45% 以上,部分集群天均 CPU 利用率可稳定提升至 55%。
- 通过在离线混部等技术手段,在线集群 CPU 利用率提升 8%-15% 不等,部分存储集群利用率提升可达 20% 以上。
资源成本
- 在保证离线业务稳定性的前提下,为小红书各类离线场景提供数百万核时的低成本算力。
- 混部集群 CPU 分配率提升至 125% 以上,相较于独占资源池,资源碎片率明显下降。
4、总结与展望
在小红书近一年多的混部技术探索中,我们在资源效能提升方面积累了较为丰富的落地经验,并取得了不错的收益。随着公司业务规模逐步增长,场景愈发复杂,我们将会面临诸多新的技术挑战。展望未来,我们的目标是建设面向混合云架构的统一资源调度能力,具体工作将围绕以下三方面展开:
- 混合工作负载调度能力支持:为了满足小红书所有业务场景的资源调度功能、性能需求,重点发展任务型工作(包括大数据、AI等 )的负载调度能力建设。
- 资源效能进一步提升:面向混合云架构,我们将推进更大规模的资源合池,推动 Quota 化资源交付。通过采用更先进的弹性、混部、超卖等技术手段,进一步提升集群资源利用率,实现资源成本的大幅度下降。
- 更高服务质量保障能力:在更具挑战性的 CPU 利用率目标下,我们将建设 QoS 感知调度能力、干扰检测能力,并依托安全容器等技术手段,解决深水区混部中可能遇到的各类干扰问题。
5、作者简介
桑铎(宋泽辉):基础技术部/云原生平台
小红书资源调度负责人,在容器资源调度、混部部署、资源隔离等方面有丰富的实践经验,目前主要负责小红书大规模容器资源调度、在离线混部等方向的技术研发工作。
黄濑(索增增):基础技术部/云原生平台
小红书资源调度资深研发工程师,主要负责资源调度、工作负载编排相关的研发工作。
灰仔(叶杨婕):基础技术部/云原生平台
小红书资源调度研发工程师,主要负责在离线混部方向研发工作。
特别感谢:小红书音视频架构组、数据引擎组、交易算法组所有业务方同学。