背景概述
每年双十一创造奇迹的背后,是巨大的成本投入。为了完成对流量峰值的支撑,我们需要大量的计算资源,而在平时,这些资源往往又是空闲的。另一方面,为了在极端情况下,如机房整体断电等还能保障阿里巴巴的业务不受损失,也需要在全国各地建立冗余资源。而且就算是一天当中,在线服务的负载也是不一样的,白天一般情况下要比凌晨高得多。根据盖特纳和麦肯锡前几年的调研数据,全球的服务器的CPU 利用率只有 6% 到 12%。即使通过虚拟化技术优化,利用率还是只有 7% -17%,而阿里巴巴的在线服务整体日均利用率也在 10% 左右。
另一方面,全球从 IT 时代全面走向了 DT 时代,现在又在向更深入的 AI 时代迈进。各各样的大数据处理框架不断涌现,从 Hadoop 到 Spark,从 Jstorm 到Flink,甚至包括深度学习框架 Tensorflow 的出现,成千上万的数据分析背后是大量的计算任务,占用了大量的计算资源。由于计算任务占用的计算量很高,CPU 水位通常在50%-60% 以上,不同于在线服务,计算任务的峰值通常出现在凌晨,水位甚至能达到 70% 以上。所以我们往往就会建立独立的计算任务集群。
很多人都被车堵过,而堵车的时候,并不是所有的车道都在堵车。有一个比较有趣的情况,我们称之为潮汐现象,而它造成的问题是在早高峰的时候是进城方向堵车,而晚高峰是出城方向堵。而为了缓解这个问题,我们使用了潮汐车道的方式。
那么同样的原理,是否如果能让这两个集群混合起来部署,让计算任务的一部分任务跑到在线服务的资源之上,把在线服务空闲的资源利用起来呢?答案是肯定的。
混部技术简介
混部技术示意图
把集群混合起来,将不同类型的任务调度到相同的物理资源上,通过调度,资源隔离等控制手段 , 在保障 SLO 的基础上,充分使用资源能力,极大降低成本,我们称这样的技术为混部(Co-loaction)。
打个比方,跑在容器里的在线服务就像石块;而计算任务我们把它比喻成沙子和水。当在线压力小的时候,计算任务就占住那些空隙,把空闲的资源都使用起来,而当在线忙的时候,计算任务就立即退出那些空隙,把资源还给在线业务。这样的技术一方面在平时,我们可以极大地提升资源的利用率;另一方面,在大促活动需要突增在线服务器的时候,又可以通过在线业务占用计算任务资源的方式,来顶住那短暂的峰值压力。
从原理中我们可以看到可以混部在一起的任务有两个比较重要的特征:
1.可以划分优先级:一定需要优先级比较低的任务,它们能像水和沙子一样,随时能被赶走,而不会受到不可承受的影响,让优先级高的任务不受干扰。在线的特点是:峰值压力时间不长,对延时比较敏感,业务的压力抖动比较厉害,典型的如早上 10 点的聚划算活动,就会在非常短的时间内,造成交易集群的压力瞬间上升 10 几倍,对于稳定的要求非常高,在混部的时候,必须要保证在线的通畅,需要有极强的抗干扰能力。而计算任务的特点是:平时的压力比较高,相对来说计算量可控,并且延迟不敏感,失败后也可以重跑。至少需要几分钟跑完的计算任务,相对于几秒甚至几十秒的延迟,并不会产生严重的问题,正好可以承提起水和沙子的角色。
2.资源占用互补性:两种任务在不同的时间点对水位的占用不一样。如在线服务是,平时比较低,大促时比较高;凌晨比较低,白天比较高。而计算任务则反过来,平时比较高,大促时可以降级;凌晨非常高,白天却要低一些。
这种方式带来的成本节省是非常巨大的:假设数据中心有 N 台服务器,利用率从R1 提高到 R2,不考虑其他实际制约因素的情况下,节约 X 台,那么理想的公式是:
N*R1 = (N-X)*R2
=> X*R2 = N*R2 – N*R1
=> X = N*(R2-R1)/R2
也就是说如果企业有 10 万台服务器,利用率从 28% 提升到 40%,代入上述公式,就能节省出 3 万台机器。假设一台机器的成本为 2 万元,那么节约成本就有6 个亿。
2015 年,Google 发表了 Borg 论文,其中就提到了在线服务与计算任务之间的混合运行,也就是我们说的混部技术。Borg 论文中描述了 Google 由于采用了这项技术,为 Google 节省了 20%-30% 的机器规模。
混部技术的历程
阿里巴巴早期混合云架构
大家都知道这今年阿里巴巴双十一的交易峰值是每秒 32.5 万比,相比去年几乎增加了 1 倍,但是这样的高峰却只有 1 小时左右。为了让交易的成本降低,从 2014年开始,我们一方面通过阿里云的公有弹性云资源降低成本,另一方面也开始研究混部相关的技术。
混部能产生这么大的帮助,可是业界能使用在生产的没有几家公司,其原因也非常简单,第一个是规模,第二个是技术门槛。当你机器规模不够大的时候,显然意义不大。而在技术上,计算型任务通常都可以把利用率跑到很高,如果计算型任务和在线型业务运行在同一台机器上,怎么避免计算型任务的运行不会对在线型业务的响应时间等关键指标不产生太大的影响呢,这个需要在技术上有全方位的突破,而阿里巴巴从无到有,花了 4 年多的时间才让这项技术在电商域得以大规模落地。
- 2014 年,我们最主要的工作是进行技术论证,方案设计,以及相关的一些实验性研究
- 2015 年,我们开始了日常测试环境的测试工作。这一期间让我们总结了相当多的问题:如调度融合问题、资源争抢隔离问题、存储依赖问题、内存不足问题等等
- 2016 年,当我们把大部分问题都解决掉时,我们开启了线上 200 台左右的小规模验证。由于电商的金融属性,对于抗干扰要求特别高,在不断的业务考验下,我们不停地修正着技术方案
- 2017 年,经过一年的磨合,混部的整体技术终于走向了成熟和大规模生产。阿巴巴双十一当中,约有 1/5 的流量是跑在混部集群之上
混部非混部集群资源使用对比图
在日常情况下,我们可以把在线服务的集群的 CPU 利用率从非混部的 10%提升到混部的 40% 以上,整体的成本节省在 30% 以上。而在线受到的干扰在 5%以内。
混部非混部集群平均服务响应时间对比图
混部调度的架构
混部调度的架构示意图
在混部集群中,我们的两个调度平台同时自主运行,sigma 管理在线服务容器的调度,而 Fuxi 管理 ODPS 上的的计算任务。为了让这两个调度器能一起进行工作,在中间我们使用了零层与零层管控来协调两者之间的资源分配。
1. 在线服务容器调度器 Sigma 的特点是:
- 兼容 Kubernetes 的 API,和开源社区共建
- 采用阿里兼容 OCI 标准的 Pouch 容器
- 经历过阿里多年的大规模使用和双十一的验证
- 面向海量数据处理和大规模计算类型的复杂应用
- 提供了一个数据驱动的多级流水线并行计算框架,在表述能力上兼容 MapReduce,Map-Reduce-Merge,Cascading,FlumeJava 等多种编程模式
- 高可扩展性,支持十万以上级的并行任务调度,能根据数据分布优化网络开销。自动检测故障和系统热点,重试失败任务,保证作业稳定可靠运行完成
3. 通过零层的资源协调机制,让整个集群平稳地管理并运行进来:
- 混部集群管理
- 各调度租户之间的资源配比
- 日常与压测大促等时段的策略
- 异常检测与处理
2.内核:在资源真正发生竞争的极端情况下,根据任务的优先级,如何做到既能保障高优先级任务不受影响,又能控制影响到的低优先级任务伤害最低。它是被动触发,保底的必须手段,生效快。
在调度上,我们主要从以下方面进行优化:
1.日常的分时复用:由于波峰波谷的存在,在线服务与计算任务在一天中的峰值正好可以产生互补的情况,所以我们可以通过白天夜晚的分时复用提高资源的使用效率。
- 对集群进行资源使用的画像
-
在线服务凌晨 1-6 点为低峰,离线是高峰,针对这一特性进行水位调整
-
通过在线服务资源画像智能挑选空闲容器进行 offline 处理
2.大促的分时复用:电商类业务由于大促的存在,在大促或压测的时候会产生比平时高几倍十几倍的压力差,如果这个时候对计算任务的资源进行降级让给在线服务全使用,就可以轻松地支撑起那短暂的脉冲压力。
- 日常态,计算任务占用在线服务的资源
-
大促态,在线服务占用计算任务的资源
-
1 小时快速完成切换,提高资源的利用
3.无损有损降级:在线服务会有一些特定的业务高峰时间,比如压测,比如大促等。那么如何在降级计算任务的时候,带来的影响尽可能小呢?这里我们就需要对降级的方案做特殊的处理。
- 无损降级:由于在线服务的 NC 平均利用率不高,再加上 70% 的计算任务小于 3 分钟,那么只要压测或大促在降级之后的 5 分钟,计算任务对于在线服务的干扰就不会那么大了。另一个问题是做到分钟级的恢复,这样只有当在线服务的真正高峰才会受到影响,而这个时间段又是比较短的,那么影响就会降低。
-
有损降级:当在线服务受到严重影响的时候,我们也可以做到秒级的 Kill,迅速恢复,让在线服务的影响降到最低。
4.计算任务选取:计算任务我们比喻成沙子,但是沙子也有大有小,也需要对沙子进行筛选,才能把空隙填充满但又不溢出。
- 对作业进行资源使用的画像,分析出作业需要消耗的资源。
-
通过 0 层来获得宿主机剩余的确切计算资源能力
-
挑选符合条件的最佳作业,尽可能最大利用,也尽可能降低竞争。
5.动态弹性内存:由于我们的存量资源并没有考虑到混部,内存与 CPU 都是按照在线服务原来的使用配比,并没有富余的内存存在,但是由于计算增加了,内存就成了瓶颈,原来在线服务以静态分配内存的方式就不再适合。
- 在线服务的内存加入共享分组
-
基于在线服务的实际内存使用,动态调整计算任务占用的内存水位
-
当在线服务压力突增时,通过迁移或 Kill 任务的方式,自动降级计算任务的内存水位。计算任务释放内存后,内核马上进行资源回收
-
当整机发生 OOM 时,优先杀计算任务中优先级低的任务
6.存储计算分离:在线服务是重 IOPS,但是存储量不大,所以使用的都是SSD 的小盘;而计算任务都是重存储量,但 IOPS 不大,所以使用的都是HDD 的大盘。而在混部的时候,如果还是以本地盘的方式来处理数据,计算混杂在一起,对于调度复杂度是几何级的提升。所以我们需要把本地盘虚拟化成统一的存储池,通过远程的方式,根据不同的需求访问不一样的存储设备。另外阿里也开始大规模建设 25G 的网络设施,整个网络能力提升,也让远程访问变得像本地一样快。
内核隔离,我们主要从以下方面进行处理 :
1. CPU 调度优化:这是隔离当中最重要的一项,当在线业务使用 CPU 压力上升,计算任务必须要毫秒级的自适性退出。
● CPU 抢占
○ 按照 CGroup 分配优先级 (cpu.shares)
○ 高优先级任务可以抢占低优先级任务的时间片
● 规避 HT(noise clean)
○ 避免离线任务调度到在线任务相邻的 HT 上
○ 保证已经运行的离线任务在在线任务于相邻 HT 上唤醒后迁走
● L3 Cache 隔离
○ 通过 BDW CPU 的特性 CAT 来进行对 Cache 访问的流量控制,进而达到
限制低优先级计算任务对 CPU 的占用。
● 内存带宽隔离
○ Memory Bandwidth Monitoring ,通过时实监控来进行策略调整
○ Cfs bandwidth control 调节计算任务运行时间片长度。通过缩短时间片,
让高优先级任务更容易获得占用 CPU 的机会。
2. 内存保护
● 内存回收隔离
○ 按照不同的 CGroup 分配优先级
○ 增加组内回收机制,避免全局内存回收干扰在线任务
○ 按优先级确定内存回收的权重,在线任务的内存被回收的更少
● OOM 优先级
○ 整机 OOM 时,优先杀低优先级任务
3. IO 分级限制
● 文件级别的 IO 带宽隔离 ( 上限 )
○ 新增 blkio 的控制接口
○ 限制 IOPS,BPS
● 文件级别的保低带宽 ( 下限 )
○ 允许应用超出保底带宽后使用富余的空闲带宽;
● Metadata throttle
○ 限制特定操作的 metadata 操作,例如一次性删除大量小文件。
4. 网络流量控制
● 带宽隔离
○ 隔离本机带宽(TC)
○ Pouch 容器间的带宽隔离
● 带宽共享(金、银、铜)
○ 在离线间可以存在共享带宽
○ 进程间按照优先级可以抢占带宽
混部的未来规划
混部技术经过四年的磨炼,终于在 2017 支撑起了阿里巴巴双十一核心交易流量的 20%,并且也作为阿里巴巴未来数据中心建设的标准技术。而在未来的一年中,混部技术会向更精细化的调度能力演进。
在场景上,会更多元化,无论是实时计算,还是 GPU,甚至是 FPGA,都能够混部在一起。在规模上,也会从十万核级别的集群往百万核级别的集群扩展。在资源画像能力上,会引入更多的深度学习,提高预测的准确性,为利用率再次大幅度提升打基础。在调度能力上,会建立更加完善的优先级体系,在资源分配与协调上不会以在线服务和计算任务来区别,而是以通用的优先级来调度,解决更多资源类型部混问题。总结一句话,让混部真正成为调度的一种通用能力。
原文发布时间为:2018-02-12
本文作者:潇谦