小红书如何做混部?
作者:宋泽辉(小红书)、张佐玮(阿里云)
编者按:
Koordinator 是一个开源项目,是基于阿里巴巴内部多年容器调度、混部实践经验孵化诞生,是行业首个生产可用、面向大规模场景的开源混部系统,致力于提升应用服务质量,优化资源使用效率。自 2022 年 4 月正式开源以来,吸引了业界众多优秀工程师的贡献参与和讨论。
小红书是 Koordinator 社区的活跃成员,自项目诞生初期就深度参与了一系列重要功能的演进。
背景介绍
随着小红书业务的高速发展,各类在线、离线业务对于计算资源的需求也在快速增长。与此同时,部分在线集群天均利用率水位却维持在较低水平,造成这一现象的主要原因有以下几点:
在线服务资源使用量随着终端用户的使用习惯呈现稳定的潮汐现象,夜间 CPU 利用率极低,导致集群均值 CPU 利用率较低;
业务保有大量的独占资源池,资源池割裂产生大量的资源碎片,拉低 CPU 利用率;
业务为了稳定性考虑,会过量囤积资源,进一步拉低 CPU 利用率。
基于以上背景,为了帮助业务降低资源使用成本,提升集群 CPU 利用率,小红书容器团队从 2022 年开始,通过规模化落地混部技术来大幅提升集群资源效能,降低业务资源成本。
技术演进
小红书混部技术演进分为以下四个阶段:
阶段一:闲置资源再利用
早期集群资源管理粗放,集群中存在大量业务独占资源池,因为资源碎片等因素存在大量低分配率的低效节点,散落在各个集群中的低效节点形成大量资源浪费。另一方面,部分基于 K8s 发布的转码类近线/离线场景,全天时段均存在大量计算资源需求。
基于以上背景,容器平台通过技术手段将集群中的闲置资源收集起来,分配给转码类业务场景使用。
我们通过 virtual-kubelet 打通元数据集群与物理集群,将闲置资源汇聚起来,在元数据集群分配给转码类场景近线/离线计算服务。策略方面,二次调度器负责巡检集群所有节点,识别为低效节点后标记出来,virtual-kubelet 获取物理集群中的低效节点可用资源作为集群闲置资源二次分配给离线转码,同时二次调度器需要保证一旦在线服务有资源需求,将会立刻驱逐离线 pod 并归还资源。
阶段二:整机腾挪分时复用
搜推广等业务的独占资源池,CPU 利用率潮汐现象明显,夜间利用率极低,资源池中的单个节点往往也只部署一个大规格业务 Pod。基于以上背景,平台通过弹性能力(HPA),在凌晨业务低峰期按比例对在线业务缩容,腾挪空出整机,并将转码、训练等离线 pod 在该时段运行起来,起到利用率“填谷”的效果。
具体实施时,需要确保在线服务能在规定的时间内全部被拉起。为此,策略方面我们实现了离线提前退场,并通过调度器抢占机制兜底,确保在线服务在业务高峰期来临之前能被全量及时拉起。
阶段三:常态混部
为了降低资源碎片率,降低业务资源持有成本,平台持续推进业务大规模合池,将业务由独占池迁至平台托管的公共混部池,通过合池、资源超卖等技术手段,CPU 分配率得到有效提升,但依旧无法解决合并后的资源池夜间利用率较低等问题。
另一方面,合池后的复杂混部场景下,整机腾挪分时混部离线的调度策略很难再继续实施,平台需要通过建设更为细粒度的资源管理与调度能力来实现均值利用率提升的目标,具体包含以下几点:
调度侧:
通过动态超卖技术获取可二次分配给离线的可用资源量,并抽象出离线资源视图让 K8s 调度器感知到,调度器调度离线负载到对应节点上,实现离线对节点利用率的“填谷”效果;
通过负载调度,尽可能避免在线服务被调度到高负载机器,让集群中节点负载更加均衡;
通过二次调度,驱逐负载热点机器上的高利用率服务,使得集群负载处于动态均衡状态。
单机侧:
支持 QoS(Quality of service) 保障策略,根据服务的 QoS 等级提供差异化的运行时资源保障能力;
支持干扰检测、离线驱逐等能力,当离线对在线敏感服务产生干扰时,第一时间驱逐离线。
通过以上技术手段,可以有效保障服务混部时的稳定性,从而常态化的让在线离线工作负载混跑在节点上,实现利用率填谷效果的最大化。
架构设计与实现
小红书容器资源调度架构设计如图所示:
小红书各类业务场景通过各类发布平台、任务平台提交后,通过上层负载编排能力,以 pod 形式下发到统一调度系统。统一调度系统基于不同的调度需求,对在线服务提供强保障的资源交付能力,差异化的 QoS 保障能力,对离线服务提供最小资源需求的保障能力和极致的弹性能力。
调度侧:
离线调度:coscheduling;
二次调度:热点驱逐,碎片整理;
负载调度:基于 CPU 水位;
资源视图:模拟调度。
单机侧:
压制策略:bvt 压制,内存驱逐;
QoS 保障:绑核,超线程干扰抑制等;
Batch 资源上报:Batch 可用资源计算,上报;
指标采集(from kernel):psi,sched info 等;
干扰检测:基于 cpi、psi,业务指标的干扰检测。
离线调度资源视图
离线服务资源调度的基本原理是基于在线服务负载感知能力的动态超卖,具体实现是将节点空闲资源二次分配给离线业务:
其中离线可用资源为节点上的空闲资源(包含未分配资源和已分配未使用资源之和),扣除安全预留资源之后剩余资源,离线可用资源计算公式如下:
离线可用资源=整机资源–预留资源-在线服务实际使用量
将计算出的离线可用资源量按照时间分布后如图所示(图中绿色部分):
实际落地过程中,为了避免离线可用资源随在线服务资源使用波动而大幅波动,从而影响离线资源质量和离线服务运行稳定性,通过资源画像对上述公式中的在线服务实际使用量数据进一步处理,去除数据噪点,最终计算出一个相对稳定的离线可用资源量(图中绿色部分),如图所示:
混部 QoS 保障策略
QoS 分级
按照业务对于服务质量(QoS: Quality of Service)的需求,我们将小红书的业务类型简单的划分为三个 QoS 级别,如下表所示:
QoS 保障
根据服务的 QoS 需求,节点侧会做 Pod 粒度的分级资源保障,实现各个资源维度差异化 QoS 保障策略,具体的保障参数如下:
在 CPU 核调度层面,分别设置了三种绑核类型,并设计了一套精细化 CPU 核编排策略,分配示意图如下:
三种绑核类型分别为:
exclusive(不推荐)
特点:绑定 cpuset 调度域,CCD 感知,numa 绑定,独占排他
场景:极为敏感的搜推广大规格延迟敏感服务
share
特点:绑定 cpuset 调度域,CCD 感知,numa(可选)绑定,share/exlusive 排他,可与 none 类型业务共享
场景:容忍部分干扰的 Java 微服务,应用网关,web 服务
reclaimed
特点:无 cpuset 绑定,可能与非 exlusive 绑核模式业务共享核,核的分配完全交由内核,CPU 资源并非 100% 能得到满足
场景:batch 类离线服务,部分对延迟无要求的计算服务
离线驱逐
极端场景下,如整机内存使用率较高,有触发 OOM 风险,或者离线业务 CPU 长期得不到满足,单机侧支持按照离线服务内部定义的优先级配置,资源用量,运行时长等多维度综合算分排序后按序驱逐。
离线业务场景
小红书作为一个数亿用户的内容社区,其离线业务场景丰富多样,其中包含大量视频类,图片类转码场景,搜推,cv/nlp 算法推理训练,算法特征生产,数仓查询等离线场景,具体来讲,包含以下业务类型:
近离线转码场景(已容器化)
Flink 流式/批式计算(已容器化)
Spark 批式计算 (未容器化,on yarn)
cv/nlp 算法回扫场景(已容器化)
训练场景 (已容器化)
通过提供以 K8s 为底座的在离线统一调度能力,将这些离线业务与在线服务混合部署在统一计算资源池内,为在线服务提供差异化的资源质量保障,为离线服务提供海量的低层本算力,实现资源效能的提升。
K8s 与 Yarn 混部方案
小红书内部商业化,社区搜索等业务存在大量的算法类 Spark 任务因为离线集群资源紧张导致任务堆积,不能得到及时处理,同时在线集群在业务低峰时段资源使用率较低;另一方面,相当占比的 Spark 任务资源调度仍旧运行在 Yarn 调度器上,在这样的背景下,为了降低业务迁移成本,方案选型方面,我们选择与 Kooridinator 社区合作,采用 Yarn on K8s 混部方案来快速落地 Spark 离线场景混部,具体方案如图所示:
其中容器化的在线、离线工作负载通过 K8s 链路发布到在线集群内,Spark 作业通过 Yarn ResourceManager 调度到具体节点,并由节点上的 Nodemanager 组件拉起。其中 Nodemanager 通过容器的方式部署在在线 K8s 集群内,除此之外,还涉及到以下组件:
调度侧
koord-yarn-operator :支持 K8s 与 yarn 调度器资源视图双向同步;
节点侧
copilot:NodeManager 操作代理,提供 Yarn Task 管控接口;
Neptune-agent/koordlet:离线资源上报,节点离线 Pod/task 管理,冲突解决,驱逐,压制策略;
支持 K8s 与 YARN 混部的核心能力目前已经在社区研发完成,在 Koordinator 1.4 版本进行发布。
多调度器资源同步
K8s 调度器与 YARN 调度器之间原本独立且相互不感知,为了共享分配在线集群节点上的总可用离线资源,需要通过 koord-yarn-operator 组件来做两个调度器之间的资源双向同步和协调,并实现两个同步链路:
K8s->YARN 调度器资源同步链路,负责同步 Yarn 视角离线资源总量,其中 YARN 离线资源总量计算如下:
YARN 离线资源总量=离线总可用量-K8s 侧节点已分配
YARN->K8s 调度器资源同步链路,负责同步 YARN 已分配资源量,其中 K8s 离线资源总量计算如下:
K8s 离线资源总量=离线总可用量-YARN 侧节点已分配
基于各自节点离线资源视图,两个调度器分别做出调度决策,调度 K8s 离线 Pod 与 YARN Task 到节点上,由于同步过程不适合加锁,可能会出现资源被过量分配的问题:
具体解决措施是在单机侧增加了仲裁逻辑,当节点已分配离线服务资源量长期超过节点可用离线资源,且离线使用率持续较高,存在离线服务得不到资源被饿死的可能,单机侧则会根据离线服务的优先级,资源占用量,运行时长等因素综合算分并按序驱逐。
阿里云 EMR 产品化支持
与此同时,阿里云 EMR 团队在产品层面提供了混部功能的开发支持,在兼容 EMR 原有日志,监控,运维逻辑的基础上,支持了 K8s 集群弹性扩缩容 NodeManager Pod 的能力。
落地收益
截至目前,小红书混部能力覆盖数十万台机器规模,覆盖算力规模数百万核,支持数万规模在线、离线场景服务的资源调度。 通过大规模容器混部的持续推进,小红书在资源成本效能等方面都取得了显著收益,具体包含以下两方面:
CPU 利用率
在保证在线服务服务质量的前提下,在线混部集群天均 CPU 利用率提升至 45% 以上,部分集群天均 CPU 利用率可稳定提升至 55%。
通过在离线混部等技术手段,在线集群 CPU 利用率提升 8%-15% 不等,部分存储集群 CPU 利用率提升可达 20% 以上。
资源成本
在保证离线业务稳定性的前提下,为小红书各类离线场景提供数百万核时的低成本算力。
混部集群 CPU 分配率提升至 125% 以上,相较于独占资源池,资源碎片率明显下降。
社区共建历程
小红书是早期参与 Koordinator 社区的公司之一,2022 年 4 月,Koordinator 正式开源,同年 6 月,小红书内部启动了在离线混部项目,开始参与 Koordinator 方案设计与代码提交。2022 年 8 月,小红书与社区共建了 runtime-proxy 组件,并在内部场景落地。2023 年 4 月,小红书在社区主导启动了 YARN 与 K8s 混部项目,2023 年 8 月,该方案在小红书内规模化落地。
截至目前,依托 Koordinator 的助力,小红书的混部已经覆盖公司数万台节点,提供数十万核离线资源,整体混部集群的利用率提升至 45% 以上, 取得了不错的落地效果。
总结与展望
在小红书近一年多混部技术探索过程中,我们在资源效能提升方面积累了较为丰富的落地经验,并取得了不错的提升效果,随着公司业务规模逐步增长,场景愈发复杂,我们将会面临诸多新的技术挑战。下个阶段我们的目标是建设面向混合云架构的统一资源调度能力,具体工作将围绕以下三方面展开:
混合工作负载调度能力支持: 包括大数据、AI 在内的任务型工作负载调度能力建设,满足小红书所有业务场景的资源调度功能,性能需求;
资源效能进一步提升: 面向混合云架构,推进更大规模的资源合池,推进 quota 化资源交付,通过更加激进的弹性,混部,超卖等技术手段,实现集群资源利用率的进一步提升,资源成本的大幅下降;
更高服务质量保障能力: 在更为激进的 CPU 利用率目标背景下,通过建设 QoS 感知调度能力,干扰检测能力,依托安全容器等技术手段,解决深水区混部中可能遇到的各类混部干扰问题。
Koordinator 社区近期规划
再接下来的几个版本中,Koordinator 将在以下几个方面进行重点投入:
调度器性能优化: 支持等价类调度,通过合并 request 相同的 pod,避免 filter、score 等调度过程的重复计算。
Network QoS: 网络维度容器服务质量,保障高优先级带宽,设计 request/limit 模型,保障最低带宽需求。
大数据负载: 支持 Gang 调度原子抢占,按分组整体抢占 Pod;面向 Hadoop YARN 任务的 QoS 策略适配。
资源干扰检测: 基于底层指标、感知容器资源竞争情况,识别异常 Pod,消除干扰并反馈调度链路。
钉钉搜索群号:33383887 加入 Koordinator 社区钉钉群。
版权声明: 本文为 InfoQ 作者【阿里巴巴云原生】的原创文章。
原文链接:【http://xie.infoq.cn/article/78da4ddd29a17b4b6a83798b8】。文章转载请联系作者。
评论