作者:易立
本文根据作者在 9 月 20 日由中国计算机学会组织的 CCF TF 会议演讲整理。
今天数字化的生产与生活方式成为后疫情时代的新常态,云计算也已经成为社会的数字化基础设施。如何利用云原生技术帮助企业实现降本增效是很多 IT 管理者和开发者关注的话题。
背景
阿里云容器产品家族
阿里云容器产品 ACK 覆盖了从公共云、边缘云、到本地数据中心的各个场景,让所有需要云能力的地方,都能获得统一的容器基础设施。
容器服务 ACK 支持了外部数万企业客户 IT 架构的容器化,优化上云成本,提升用云效率,同时 ACK 也是很多阿里云产品的基础设施,支撑云产品的 Serverless 化。比如阿里云上消息服务、RDS 数据库、数据湖分析、弹性 AI 服务等等。同时容器服务也支撑了阿里集团的全面云原生化,目前规模已达到数千万核。
FinOps 与云原生
站在经济学角度,云计算是将 IT 的固定成本转化成为可变成本,这对企业传统的 IT 成本管理方法也带来了挑战。于是 FinOps 理念也应运而生。
在 FinOps 基金会的定义中:FinOps 是一种不断发展的云财务管理科学与实践,通过数据驱动的支出决策帮助工程、财务、技术和业务团队进行协作,使组织能够获得最大的业务价值。
FinOps 是“Finance”和“DevOps”的综合体,强调业务团队和工程团队之间的沟通与协同。在 FinOps 实施过程中我们可以将其划分为:成本洞察、成本优化、成本运营三个阶段,帮助企业通过数字化手段实现成本可视,可优化与可控。
利用云原生技术实现上云效益优化,可以从几个层次入手:
在基础设施层,我们关注的要点有:
- 用法 – 选择合适的算力适配工作负载,比如对高性能计算等场景,选择计算型实例,或者利用 GPU、RDMA 等加速设备实现降本提效。
- 用量 – 根据工作负载的特征,进行合理的容量规划。
- 价格 – 选择包年包月、按量付费,采用不同计费方法,在资源的确定性、成本之间进行合理取舍。
在容器编排层,我们关注在分布式集群上,让应用更加稳定、高效地运行,并充分利用云的弹性能力降低成本。
在应用架构层,我们既需要解决架构中的性能瓶颈,也需要关注应用架构的现代化,并将稳定性、可观测性、安全等在研发流程左移,实现应用生命周期中的成本效率优化。
今天我会将聚焦在容器编排中的智能弹性、任务混部与数据加速等几个方面介绍如何实现成本优化和效率提升。
Kubernetes 实现基础设施弹性与应用弹性
弹性是云最核心的能力之一,可以有效降低计算成本,ACK 在资源层和应用层提供了丰富的弹性策略。
在资源层,当 K8s 集群资源不足时,ACK 集群可以利用 cluster-autoscaler 在节点池中自动创建新的节点实例。ACK 可以根据应用负载,选择 ECS 虚拟机、神龙裸金属实例进行扩容。
基于阿里云强大的弹性计算能力,可以在分钟级实现千节点扩容。在 ACK 集群中一个更加简化的方案是利用 ECI 弹性容器实例来实现弹性。ECI 基于轻量虚拟机提供了 Serverless 化的容器运行环境,具备强隔离、高弹性、免运维、免容量规划的特性。弹性容器实例可以在 30 秒内扩容 3000 Pod,新浪微博利用 ECI 可以轻松应对突发的新闻事件;自动驾驶模拟仿真客户可以在 1 分钟内拉起数万核算力进行计算。
值得一提的是,我们可以使用 ECS 或者 ECI 的竞价实例,利用阿里云的空闲计算资源,成本折扣可以低至按量付费实例的 90%。竞价实例非常适合无状态和容错性好的应用,比如批量数据处理或者视频渲染等。
在应用层,Kubernetes 提供了 HPA 的方式进行 Pod 的水平伸缩,和 VPA 进行 Pod 的垂直伸缩。ACK 还内建了基于机器学习的 AHPA 方案来进一步简化弹性体验,提升弹性的 SLA。
应用水平伸缩面临的挑战与解决之道
在实践中,很多业务都存在波峰波谷,如果采用固定实例数的方式会造成较大的资源浪费。因此 Kubernetes 中提供了 HPA 实现按需扩容实例数量,减少资源浪费。
HPA 可以根据应用负载变化调整设置实例数量,当应用负载高时扩容,当应用负载低时则缩容实例。但是 HPA 存在两个不足:
- 弹性的滞后性。弹性伸缩基于对监控指标的被动响应,此外由于应用本身启动、底层资源扩容也需要一定时间。如果当业务高峰到达再扩容,有可能导致业务受损;
- 配置的复杂性。HPA 的运行效果取决于弹性阈值的配置,配置过于激进可能导致应用稳定性受影响;配置过于保守,成本优化的效果就大打折扣。需要反复尝试才能达到一个合理的水平。而且随着应用的变化,也会需要重新调整弹性策略。
CronHPA 是用户根据业务的周期性设定定时规则,在指定时间进行实例数伸缩,结合 HPA 可以在业务高峰期到来之前完成扩容,具备很好的确定性。它的缺点是手动设定较为复杂。
为此,达摩院团队和阿里云合作提出了一种智能化弹性伸缩方案 AHPA,可以根据历史时序数据进行主动预测,提前扩容,避免弹性滞后。并且会根据实时数据动态调整主动预测结果,兼容周期变动等场景,减少人工干预。
AHPA
核心办法
AHPA 整体架构如图 1 所示,分为数据采集、预测及弹性伸缩三大部分。
- Data Collection 模块负责从数据源收集监控 Metrics 指标并将数据转为统一的格式传入给 Prediction 模块,兼容多种数据源,支持多种扩缩容指标。
- Prediction 模块负责根据输入指标预测所需的 Pod 数量。Preprocessing 负责数据预处理,比如处理缺失数据等。完成预处理后将时序数据传递给 RobustScaler 算法进行分析和预测。
- Scaling 模块根据 Prediction 给出的结果,对 Pod 数量进行扩缩容。为保证应用平稳运行,其中 ScalingProtection 组件会对算法预测出的 Pod 数量进行修正,采取快速扩容,缓慢缩容的策略。
预测模块中 RobustScaler 的算法框架实现如图 2 所示。
- 其中 Forecasting 组件用于时序数据分解。首先利用 RobustPeriod 算法检测数据是否有周期性。如果数据存在周期性,则调用 RobustSTL(Seasonal-Trend Decomposition)算法分解出数据的趋势、周期及残差项;如果数据没有周期性,则调用 RobustTrend 算法分解出趋势和残差项。
- ResourceModel 组件用于资源模型构建,该模型的输入为指标的时序数据,输出为 Pod 数量。模型选用了统计学中的排队模型。具体的模型与输入的指标有关,单指标一般采用线性模型,多指标时往往采用非线性模型。
- Planning 组件分为 Proactive 及 Reactive 两种模式。Proactive 根据历史指标数据进行主动预测,Reactive 根据实时数据进行被动预测。两种模式的预测结果进行处理后输出最终的扩缩容策略。
实验结果
AHPA 采用的算法相比其他算法相比,具有较少的训练数据量,更好的通用性和鲁棒性等优势。
- AHPA 可以帮助客户识别业务是否存在周期性;
- 当数据存在周期性时,AHPA 对数据缺失、毛刺以及业务变更引发的数据周期变化等有很强的鲁棒性;
当数据不存在周期性时,AHPA 因具备一定的预测能力,可以提前感知数据趋势变化;对数据丢失、噪音等有很强的鲁棒性;
AHPA 相关论文也被 ICDE、SIGMOD 等顶会收录。
AHPA 基于预测的自动弹性
AHPA 经在菜鸟 PaaS 平台、阿里云智能语音服务多种场景经过验证。
在智能语义交互场景中, 90% 的实例可以在业务来临之前就绪。相比之前采用 HPA 方案,CPU 利用率提升 10% ,资源成本节省 20%。
分布式系统中资源调度的复杂性挑战
Kubernetes 作为一个分布式集群管理系统,它的一个重要目标是:将适合的资源分配给适合的应用,满足对应用的 QoS 要求和获得最优的资源使用效率。
然而,分布式系统的资源调度有着非常高的复杂性。主要挑战包括:
- 对多形态异构资源的支持。今天应用所需的计算资源不只是简单的 CPU、内存、存储等,而且包括多样化的加速设备,比如 GPU、RDMA 等。而且,为了考虑到计算效率的最优化,要考虑到计算资源之间的拓扑,比如 CPU core 在 NUMA 节点间的布局,GPU 设备间 NVLink 拓扑等。此外随着高性能网络的的发展、GPU 池化、内存池化等相继出现,给资源调度带来更多的动态性和复杂性。
- 对多样化的工作负载的支持。从 Stateless 的 Web 应用、微服务应用,到有状态的中间件和数据应用,再到 AI、大数据、HPC 等计算任务类应用,他们对资源申请和使用方式有不同的需求。
- 对多维度业务需求的支持。调度系统在满足应用对资源需求的同时,也要满足不同的业务需求,比如计算效率、优先级、稳定性、利用率等等。
调度系统需要多样化的资源和多样化约束之间进行动态决策,整体挑战很高。
Koordinator-非侵入扩展 Kubernetes 支持任务混部
K8s 目前已经成为了容器编排和容器调度的事实标准,是云时代的操作系统。我们希望可以利用 K8s 的编排调度能力,充分利用多种应用负载之间的削峰填谷效应,让工作负载以更稳定、更高效、更低成本的方式去使用资源,这也是大家常说的任务“混部”能力。
阿里巴巴早在 2016 年就启动了云原生混部技术研发,历经多轮技术架构升级和“双 11”锤炼,目前已实现全业务规模超千万核的云原生混部,日常 CPU 利用率在 50% 左右。基于阿里集团内部超大规模生产实践经验,阿里云近期开源了云原生混部项目 Koordinator,它在 K8s 之上提供了对编排调度能力的增强。它包含三大核心能力:
- 差异化 SLO 保障:在 Kubernetes 之上抽象一套面向 QoS 的资源调度机制,比如延迟敏感型的在线类任务,和 Best effort 类型可抢占的计算任务。在提升资源利用率的同时,让低优先级的任务对延迟敏感型任务的影响 < 5%。
- QoS 感知调度:包括 CPU、GPU 拓扑感知等精细调度能力,帮助应用优化运行时性能效率,通过资源画像、热点打散等技术增强系统的调度和重调度能力,帮助应用改进运行时稳定性。
- 任务调度:支持大数据与 AI 相关的任务调度,比如 Gang、批量、优先级抢占以及弹性 Quota(队列间借用)等,从而更好地去弹性使用整个集群资源。
Koordinator 项目完全兼容上游标准的 K8s,无需做任何侵入式修改。阿里云容器服务提供了产品化支持,用户也可以基于开源项目应用在自己的场景中。这个项目还在快速发展的过程中,也欢迎大家一起共建。
差异化 SLO
Koordinator 可以让类似 Dubbo 微服务这样的延迟敏感应用与 Spark 任务这样的批处理计算任务可以同时运行在一个集群中,从而提高集群的资源利用效率。
Koordinator 提供了若干预定义的 QoS 类别,用于区分延迟敏感业务和延迟不敏感业务对运行时资源的差异化需求。Koordinator 通过资源画像算法预测,可以将高优先级应用已分配但尚未使用的资源,超售给低优先级的计算任务。这样可以将节点资源的分配率提高超过 100%。
如何保障资源超售场景下的应用稳定性是其中最大的挑战。在运行态,Koordinator 节点侧组件结合 CPU 微架构、OS、容器等多维度的资源隔离、干扰检测、干扰抑制等手段,让低优先级的任务对延迟敏感型任务的影响 < 5%。
这里面会利用操作系统内核 cgroup的一部分能力;也针对新一代云原生芯片进行优化。比如,通过 CPU 微架构的精细化拓扑感知,优化进程排布,提升缓存命中率,降低跨 NUMA 内存访问等。在 Intel 芯片之上,我们可以通过引入 RDT、HWDRC 等技术可以根据用户应用的 QoS,动态调整 L3 缓存带宽,降低由于内存带宽争抢导致的性能波动。
Spark 混部效果展示
在测试的 ACK 集群上,有两个 8 核 8G 工作节点。每个节点已经部署一个 Nginx 测试应用。
我们把 Spark 任务以混部的方式提交到集群上。这里通过 metadata 指明了其 qosClass 为 BE,也就是 BestEffort,。并通过扩展资源描述了其资源申请和限额。
通过混部,我们可以看到,系统 CPU 利用率从不足 20%提升至近 50%;而且测试应用的响应延迟只增加了 4.4%。
Koordinator 可以在保障延迟敏感型应用的 QoS 前提下,实现资源利用率提升。
QoS 感知调度、重调度
此外,在 K8s 集群中的工作负载是持续变化、弹性伸缩的。随着时间的推移,集群的资源分配状态可能会失去平衡,比如可能出现部分负载热点,可能导致应用运行延迟大幅增长。
以 CPU 负载为例,Koordinator 提供了 CPU 负载感知的调度能力,让 Kubernetes 调度意识到资源分配和实际资源利用率之间的差距,在调度打分阶段进行综合的决策,避免将负载调度到热点的节点上导致雪崩。
同时,为了持续的保障节点负载均衡,Koordinator 吸纳了社区的经验,为用户提供了下一代可扩展的重调度框架,同时提供了缺省的负载感知重调度策略,持续的驱动集群的负载编排向优化目标靠拢。
下图显示了经过 Koordinator QoS 感知调度和重调度,集群中节点资源实际利用率相对均衡,消除了热点。
越来越多的 AI/大数据应用,希望通过容器化来简化管理、提升弹性、优化资源利用率。过去 K8s 主要面向 Stateless 和 Stateful 应用,对计算任务类应用支持有限。阿里云团队和 K8s 社区展开了很多合作,完善了 Scheduler framework 并提供了一些关键的调度插件,来满足计算任务类应用对资源效率、任务特征、业务需求等的特殊性。目前,Kubernetes 社区成立 Batch Working Group,我们也一起定义 Batch Job、Queue 等核心 API、标准架构和参考实现。
我们也计划通过 Koordinator 中开放 ACK 产品中对 AI、大数据、HPC 等异构工作负载的支持。
在 ACK 中,通过 CPU 拓扑感知调度,在内存密集型任务场景,相比于社区方案有 20%~40%的性能优化,在 AI 分布式训练任务,调度器针可以自动选择最佳多 GPU 卡间互联拓扑,提供最大通信带宽,提升计算效率。对 ResNet、VGG 等典型 CV 类模型训练有 1~3 倍加速。
数据密集型应用在云原生环境上的挑战
除了调度之外,AI,大数据,HPC 等数据密集型应用云原生化,还有一些技术挑战有待解决,具体来说:
- 异构数据源带来的多样性挑战:企业中不同应用所依赖的存储实现各不相同,有 HDFS、NAS、S3/OSS等等;其数据访问的 I/O 特性也不同,比如随机读海量小文件和顺序读大文件。随着业务场景的发展,经常需要联合处理来自不同的存储系统的数据,这样带来了异构数据源访问的复杂性。
- 存算分离架构导致的 I/O 性能和吞吐的挑战:计算存储分离架构可以大大降低存储成本,并且提升计算弹性。但相应增加了了数据访问延时。这有可能导致计算性能的下降,降低 CPU/GPU 等资源的实际利用率。而随着弹性深度学习等技术的兴起,算力可以根据计算成本或者收敛效率变化而动态扩缩容,进而带来 I/O 容量规划和供给的变化。
- 跨作业数据共享效率低下的挑战:通过对模型训练集群的观察,我们发现很多训练任务使用同样的数据集。同一作业流水线上的不同步骤也可能需要访问相同的数据。但是由于这些数据重用无法被调度系统感知,导致数据被反复拉取,降低了整体计算效率,也加剧了对数据源 I/O 资源的争抢。
Fluid-数据编排的核心方法
为了能够更好的解决数据密集型应用在云原生环境上的问题,我们在开源数据编排项目 Fluid中 对“计算任务使用数据的过程”进行抽象,提出了弹性数据集 Dataset 的概念,并作为“first class citizen”在 Kubernetes 中实现。
- 数据集 Dataset,可以实现对异构数据源的统一管理和统一访问抽象。
- 通过自动缓存扩容和智能预取实现数据加速;还可以根据数据集的访问的模式,来自动优化数据缓存的生命周期策略。
- 调度系统可以自动感知多任务之间的数据集关联与血缘,基于数据共享优化作业调度。
Fluid-云原生数据编排与加速
Fluid 是阿里云容器服务团队和南京大学、Alluxio 联合发起的开源项目,目前是 CNCF 托管的 Sandbox 项目,并且在 ACK 上也有对应的产品能力。主要由阿里云容器服务团队维护。另外 Fluid 也得到了也得到许多业界同行的支持,像中国电信、SAP、百度云、腾讯云都在积极贡献。
Fluid 在架构上有几个特点:
- 零侵入 – 无缝融合 Kubernetes 生态;
- 可扩展 – 支持多种缓存引擎,比如阿里云 JindoFS、腾讯云 GooseFS、开源的 Alluxio、JuiceFS 等等;
- 高弹性 – 除了支持经典的 K8s 之外,对 Serverless 容器也进行支持,支持缓存 I/O 吞吐的水平扩展。
如果大家有兴趣可以进一步了解 Fluid 背后设计的思想的一些探索,相关论文已经被 ICDE 接收,欢迎查阅。这个领域也是非常新的一个领域,希望大家能够一起在社区参与创新。
Fluid-加速 AI 训练效果
比如在 Resnet50 图像分类模型训练中。如果直接使用 OSSFS 进行数据访问,在多机训练环境中会受到 OSS 总带宽的限制,训练性能出现衰减。利用 Fluid 缓存加速支持分布式训练,可以实现接近线性的横向扩展能力。与原方案相比,在 16 台 128 卡环境下,性能提升 80%。
在微博测试场景中,Fluid 针对海量小文件缓存优化,可以大大降低 HDFS 压力,训练速度提升 9 倍。
云原生 FinOps 成本管理,助力企业高效用云
阿里云为企业构建了先进、普惠的云原生产品家族。
2022 年 1 季度,在权威咨询机构 Forrester 发布的公共云容器平台分析师报告中,阿里云容器服务 ACK 成为比肩 Google 的全球领导者,这也是首次有中国科技公司进入容器服务领导者象限。
在 2022 年 8 月,CSDN 2022 中国开发者调查报告中,52%开发者选择阿里云容器云平台。
今年 5 月阿里云凭借在云上成本管理的产品能力,以满分的成绩通过了全部 33 个能力指标,成为国内首家通过信通院《云成本优化标准》的云服务商。
非常期待与大家共同探索,利用云原生 FinOps 产品能力和技术,助力企业实现高效用云。