刚刚过去的 2021 年,在全球经济增长放缓、疫情时起时伏、中美关系摩擦不断、国家平台监管趋严等宏观趋势叠加影响下,很多互联网厂商都遭遇了明显的市值下滑以及亏损加大,裁员消息时有耳闻,所以在 2022 年,降本增效无疑将进一步成为业界大势所趋。
在保持业务形态和投入不变的前提下,降本增效一个显而易见的方法是提升现有资源利用率,而造成资源利用率不高的原因主要有如下几个:
粗放的资源评估:研发更关注如何快速稳定的迭代产品需求,所以在服务部署时,一般按照最大流量来估计服务所需资源。但在线服务大都具有明显的潮汐特征,导致大部分时间段资源利用率都很低(10% 以下)从而造成浪费。
集群资源整合度不高:服务器的资源占用常常呈现非均衡状态,例如在线服务尤其是调用主链路上的扇出节点业务,高峰期往往呈现出 CPU 和带宽吃紧,但内存绰绰有余的情况。这导致虽然内存有冗余,但依然无法聚合等比例的其它闲置资源去形成有意义的计算实体。
业务部署隔离:因为东西部机房成本差异较大和以及容量规划等问题,很多企业会将在线机房、离线机房完全隔离开,这样不同 AZ 甚至不同地域间的在离线作业完全无法融合,资源池也无法互通流转。
而在离线混部技术作为提升资源利用率、降低成本的有效方案,受到业界的一致认可和推荐。
企业的 IT 环境通常运行两大类进程,一类是在线服务,一类是离线作业。
在线服务:运行时间长,服务流量及资源利用率有潮汐特征,时延敏感,对服务 SLA 要求极高,如消息流 Feed 服务、电商交易服务等。
离线作业:运行时间分区间,运行期间资源利用率较高,时延不敏感,容错率高,中断一般允许重运行,如 Hadoop 生态下的 MapReduce、Spark 作业。
因为在线服务资源利用率有更明显的的起伏特征,所以混部的主要场景是通过填充离线作业把在线服务各个时段的空闲资源利用起来,减少企业与日俱增的成本开支。(注:离在线混部计划另文阐述)
图 1 混部示意图
为了更形象的了解在离线混部的成本价值,我们来看一个中小型企业,4 核 8G 的机器一共有 1000 台,主要计算资源就是 4000 核,8000G。假设平均每台机器的资源使用率是 10%,那么实际使用的计算资源是 4000*10% = 400 核,8000*10% = 800G。如果我们能通过混部将资源利用率提升到 20%,那么我们只需要 500 台机器即可。假设 CPU 的平均价格是 300 元 / 核 / 年,内存的平均价格是 180 元 /G/ 年,就可以节省 2000*300 + 4000 * 180 = 132w 元 / 年。
由此可见,在离线混部的成本价值是清晰可计算且收益巨大的。
业界实践来看,谷歌利用混部技术将资源利用率从 10% 提升到 60%,每年节省上亿美金。阿里等大厂也成功借助混部将资源利用率提升了 3 倍以上,成本节省可观。
在离线混部虽然有明显的成本价值,但目前真正落地到生产环境的还是只有头部的一些大厂。究其原因,主要是在离线混部涉及服务观测、调度部署、容灾治理等多方面底层技术难题,甚至还包括组织成本核算、跨部门协同等非技术问题,有较高的实施门槛。总结起来,大致有以下几大挑战:
可观测性简单来说是通过检查系统输出来衡量系统内部状态的能⼒。从具体输出项来看,一般包括 metric、trace、log 三种方式,是系统健康运行的基石。在离线混部要追求更高的资源利用率,必然需要借助实时指标的反馈做出决策。但是可观测性在分布式及云原生时代,遇到了以下障碍:
云原生的体系,决定了服务能力和服务规模随时都在动态调整,所以端上数据收集 、传输的成本大大增加,极端情况下甚至对服务本身性能造成侵扰。
可观测性输出要形成决策意义,需要基于一些维度进行归并、拟合、建模等操作,包括使用决策树到 AI 学习等一系列分析动作。在大服务体量和实时变动的背景下,可观测性输出的分析时延、准确性都面临很大挑战。
可观测性的可视化以及延展关联分析 (BI 报表等),需要根据业务形态和需求进行深度定制,复杂性较高,缺乏直接能用的工具和手段。
在离线混部的调度决策是决定混部效果的核心,目前主要有几种决策方式:
整机分时复用:在固定的时间点 (比如凌晨以后) 跑离线作业,白天让出资源给在线服务。这种以时间维度切分的混部方式比较简单易理解,但整体资源利用率提升有限。
资源部分共享:将单机的资源整体划分为在线资源、离线资源以及在离线共享资源,各资源之间隔离,提前划分预留。这种从单机资源维度切分的混部方式比分时复用相对更精细一些,但是需要资源规格较大的机器切分才有意义。
资源完全共享:通过及时准确的资源预测手段、快速响应资源变化的能力,以及一套可以在资源水位发生变化时的服务保障措施,更高效自动化地实现机器资源复用。资源归属不预设,完全依据实时指标决策。
前一种属于静态决策,相对来说对底层可观测性体系的要求、对调度系统的高可用高性能的要求较低。后两种属于动态决策,在资源利用率的提升上比静态决策更优,但对前述支撑系统要求也更高。
由于在线服务和离线作业工作模式的差异,往往需要采用不同的调度器进行调度(比如K8s和Yarn)。混部场景下,在线调度器和离线调度器同时部署在集群中,当资源比较紧张的时候,调度器会发生资源冲突,只能重试,此时调度器的吞吐量和调度性能会受到较大影响,最终影响调度的 SLA。同时,对于大规模批量调度场景,原生的K8s只支持在线服务的调度,从而带来改造成本。
容器的本质是一个受限制的进程,进程之间通过 namespace 做隔离,cgroups 做资源限制。在云原生时代,大部分业务资源都是基于容器来隔离和限制,但是在资源超售叠加混部场景下,CPU、内存等方面依然可能存在争抢。
例如在 CPU 方面,为了保证在线服务稳定性,普遍做法是进行绑核,将在线服务绑定在某个逻辑核心上避免其他业务占用。但是绑核对于有并行计算要求的服务并不友好,核数直接决定并行效率。
在内存方面,离线作业往往会读取大量文件数据,导致操作系统会做 page cache,而原生操作系统对 page cache 的管理是全局的,不是容器维度的。
在线服务和离线作业属于不同的工作类型,将这两种负载部署在同一个节点上,会出现资源干扰,当资源紧张或者流量突发的时候,在线服务在资源使用上会受到离线作业的干扰。在离线混部最重要的目标,就是在保障在线服务和离线作业的 SLA 的同时,最大限度提高单机资源利用率。
针对在线服务,需要尽量保证其服务在流量高峰时期与混部之前的指标波动控制在 5% 之内;
针对离线作业,不能因为优先级不如在线服务,就一直处于饥饿或者频繁驱逐状态,影响离线作业总的运行时间和 SLA。
服务平行扩缩容能力
将多个业务混部到一台机器或容器,则宕机可能影响十几个甚至几十个服务,这时候就要求服务有平滑且快速的扩缩容能力,实现分钟级的业务迁移。尤其是存储类的有状态服务,甚至涉及到存算分离架构的改造,从而带来一系列包括数据一致性、响应延时的问题。
在企业内部,机器的产品线一般是固定的,成本和利用率也是按照产品线计算,所以通常情况下机器是不会在不同部门之间自由流转的。引入在离线混部之后,势必需要打破部门墙,对成本和利用率计算有一个能融合能分解的调整,才能准确反映出混部的巨大成本价值并持续精细化运营。以下是美团某部门精细化成本运营后的分解图:
图 2 成本指标分解图
通过对目前业界在离线方案方案的分析,我们可以抽象出在离线混部方案的三个划分维度:
从在离线混部的隔离类型上,可以分为独占内核和共享内核,主要取决于混部的服务内核是否独立。如果服务是混部于同一台物理机上,属于共享内核;如分属于不同物理机,则属于独占内核。
从在离线混部的部署底座上,可以分为物理机部署和容器部署。
从在离线混部的调度决策上,可以分为静态决策和动态决策。判断标准是调度决策所依赖的元素是否依赖运行过程中的实时指标。如是则属于动态决策,反之则属于静态决策。动态决策资源利用率更高,但是要做好突发状况时的资源保障。
这三个维度的组合,目前实际应用中主要是独占内核 + 物理机 + 静态决策、独占内核 + 容器 + 动态决策、共享内核 + 容器 + 动态决策这三种模式。
这种组合属于入门级的在离线混部选择,比如物理机运行服务且分时整机腾挪。
好处是能够快速实现在离线混部,收获成本降低的红利。技术门槛上,这种方式规避了前面说的复杂的资源隔离问题,并且调度决策足够清晰,服务部署节奏有明确的预期,整个系统可以设计得比较简单。
缺点是没有充分发挥出在离线混部的资源利用率潜力,目前主要是一些初创企业在应用。阿里早期在大促期间,将所有离线作业节点下线换上在线服务,也可以看做这种形态的近似版本。
在这种模型下,业务开发人员将服务部署在云原生部署平台,选择某些指标(大部分伴随着流量潮汐特性)来衡量服务负载,平台会按照业务指定规则对服务节点数量扩缩容。当流量低峰期来临时,随着业务节点数量的减少,在线服务会有大量碎片资源释放,部署平台会整理碎片资源,将碎片资源化零为整后,以整机的方式将资源租借给离线作业使用。
比较典型的是字节跳动的方案,架构图如下所示:
图 4 字节跳动在离线混部架构图
字节跳动依托于 K8s 与业务 quota 做整机腾挪的在离线混部,以集群转让节点的方式提高整体资源利用率,主要实现思路为:
当在线服务的波谷来临后,几乎所有服务都会因为弹性缩容而导致副本数降低。从整体上看,集群里节点上的 Pod 会变得非常稀疏,集群整体资源部署水位也随之降低。当集群的部署水位低于设置的阈值后,控制面会通过一定规则选取部分在线节点,将该节点上的 Pod 驱逐到别的节点上,并标记该节点不可调度,最后通过某种机制将该节点加到离线的集群中实现资源的转让。同理,当在线服务的波峰来临后,会发生一个逆向的控制过程,控制面在通知并确保离线任务撤离后,重新将节点加回到在线集群中设置为可调度状态,实现资源的回收。
字节跳动的方案基于公司自身的业务复杂度, 使用自定义 quota 而没有使用 K8s 通用的 hpa;部署方式两阶段混部:白天离线作业机器给在线服务使用, 晚上在线服务器转让给离线作业使用;仅支持容器部署,方案并未开源。
由此可见,在独占内核 + 容器 + 动态决策方案中,业务在部署服务的同时制定扩缩容规则,当流量低谷时,平台按照规则减少服务节点数量,此时在线资源会释放碎片资源。当碎片资源达到阈值,会触发在线到离线的转让逻辑,转让逻辑中首先整合碎片资源,然后将碎片资源整合为物理机,最后将物理机整体租借给离线使用。当流量逐渐恢复后,会触发在线回收转让资源逻辑,在该逻辑下,会逐渐驱逐离线任务,将资源回收。由于在线服务有很强的潮汐特性,可以通过定时定量的方式,比如晚高峰 19 点 -23 点,将指定数量的离线资源转让给在线服务使用,当 0 点时将转让的资源返还给离线使用。
共享内核 + 容器 + 动态决策
与上述几种方案最大的不同在于,转让的资源规则是动态决策的。在一个大企业中,服务数量数以万计,要求所有在线服务制定扩缩容决策是很难做到的。同时,业务在部署服务时更关注服务稳定性,常常按照最大流量评估资源,这样就导致流量低峰期有大量的资源浪费。
比较典型的是百度、腾讯、快手的方案,这里以腾讯方案为例:
图 4 腾讯 Caelus 系统架构图
腾讯在离线混部系统 Caelus 以 K8s 为依托,在 K8s 节点以容器的方式部署离线任务,实现在线服务节点转让资源给离线作业,支持特性包括:任务定级 / 调度增强 / 资源复用 / 资源画像 / 存算分离 / 任务避让 / 干扰检测等。腾讯的方案兼容 Hadoop 生态,但不支持离线作业转让资源给在线服务。该方案在腾讯内部已经被大规模应用到广告、存储、大数据、机器学习等多个 业务,平均提升 30% 资源利用率,节省了上亿成本。通过混部 Hadoop 类离线作业,大约提高了 60% 的 CPU 使用率。
共享内核 + 容器 + 动态决策的方案有两种资源视角:
在线服务资源视角,看到的是节点资源总体容量,比如当前物理机上总共有 126 核 CPU;
离线作业资源视角,看到的是节点的空闲负载,比如当前物理机还有 64 核 CPU 是空闲的;
服务部署时:
在线服务按照资源容量调度服务;
离线作业按照节点负载调度服务;
这类模型实施的难度在于资源隔离,如何避免或降低离线对在线的影响是混部方案是否成功的关键。各大厂在资源隔离方面都做了很多努力,比如更全面的指标收集、更智能的负载预判、更合理的在线资源冗余度、更精细的 eBPF 等。即使在资源隔离方面做了非常多的努力,还是难以避免共享内核模型中离线对在线的影响,方案中一般都搭配着干扰探测,当探测到在线服务受到影响时,及时止损。
从上述在离线混部方案的分析中可以看出,如果有比较强的研发实力,能够较好解决第三部分中讲到的几乎所有技术门槛,就可以挑战共享内核 + 容器 + 动态决策组合的方案,以追求极致的资源利用率和成本优化效果。如果公司研发团队在底层技术积累比较少,想快速、安全、低成本地用上在离线混部,先享受部分混部的成本优化红利,则独占内核 + 容器 + 动态决策组合的方案是首选。
结合业界绝大多数企业的实际场景,我们推出了一套一站式在离线混部方案,由算力调度引擎 BridgX 和智能运维引擎 CudgX 两个核心组件构成,如下图所示:
图 5 一种开源高可用在离线混部方案架构图
BridgX:算力调度引擎,在算力层面为在离线混部提供基础的算力调度能力,包括跨云调度能力、K8s 容器及大规格裸金属服务器切割能力以及快速弹性伸缩能力。
CudgX:智能运维引擎,为在离线混部提供自动化压测、服务指标度量、容量评估等能力,精准刻画在离线作业的资源使用画像。
整体的工作流程如下:
CudgX 负责收集服务指标,通过配置冗余度规则保持服务和节点的冗余度。当流量低峰时,CudgX 对服务节点缩容,触发在离线整合模块转让逻辑。当流量高峰时,CudgX 对服务节点扩容,触发在离线整合模块回收逻辑。
同时 CudgX 还会评估在线资源的冗余度,当在线资源冗余度过低时,CudgX 会触发 K8s 扩容逻辑,借助 BridgX 申请资源,完成在线资源扩容。当资源冗余度回归正常时则将资源退还,保证资源充足的情况下成本可控。
离线整合模块负责完成转让和回收逻辑,当在离线整合模块发现在线资源有足够多的碎片资源可以回收时,会进行一次碎片资源整理统计,将碎片资源整合为完整物理机转让给离线作业使用。当在离线整合模块发现在线资源冗余度不足时,会触发资源回收逻辑,将转让给离线作业的资源回收,完成回收逻辑。
本方案通过内核进行资源隔离,优点是在离线服务彻底分离,不存在离线作业影响在线服务的可能。
GitHub链接:
Bridgx:https://github.com/galaxy-future/bridgx
Cudgx:https://github.com/galaxy-future/cudgx
在离线混部对资源利用率提升、降低成本都有公认的明显作用,但在离线混部又是一个庞大而复杂的工程,涉及多个组件以及多个团队的协同合作。在离线混部也是一个持续优化的过程。各家大厂都投入了相当长的时间研究才开始放量铺开。我们期望通过借鉴业界成熟的混部方案,以云原生低门槛一站式的方式让在离线混部在更多企业落地,帮助业务摆脱成本烦恼,助力企业成功!
作者介绍:
舒超,目前在星汉未来担任 CTO,负责公司整体研发工作。2010-2015 年在腾讯担任技术专家,负责微博微群、消息流广告等项目;2015-2021 年在美团任基础研发团队负责人及存储中心架构师、资深技术专家,负责美团公司级的云原生服务治理体系研发与演进。
为了进一步对在离线混部技术展开深入交流,星汉未来将在 1 月 23 号下午 1: 30 举办北京站第二次 Meetup,围绕“自动扩缩容 & 在离线混部核心技术”为大家带来以下分享:
百度基础架构部云原生团队高级研发工程师星龙将为大家带来主题分享《百度云原生混部技术解密》
星汉未来 CTO 舒超将为大家带来《如何借助自动扩缩容实现在离线混部的分享》
星汉未来 CPO 胡忠想将为大家带来《支持通用 Web 自动扩缩容的智能运维引擎 CudgX 的详细产品体验》
此外参会者还可以现场体验智能运维引擎 CudgX。本次 Meetup 现场还会首发《星汉未来在离线混部解决方案白皮书》,与会者将第一时间获取。欢迎点击【阅读原文】链接报名,我们会审核后发出确认邀请,期待行业伙伴们一起参与。
周鸿祎不理解“35岁被职场抛弃”;拼多多“砍一刀”绩效打分被评为最低档;阿里宣布9人升任副总裁及以上职位|Q资讯
解读编程语言的2021:Go与Rust走向「成熟」,Kotlin、wasm、Julia「无限生长」
点个在看少个 bug 👇