图片来自 Pexels
本文为阿里巴巴高级技术专家吕奇分享的《阿里巴巴集团基础设施的云化演进》案例实录,将按照如下几个部分展开分享:
- 云化的背景
- 云化的业务基础
- 云化的资源基础
- 云化的控制引擎
- 云化的未来展望
云化的背景
双 11 带来的挑战
淘宝双 11 在近十年的时间,业务交易额增长 360 倍,交易峰值增长 1200 倍,从最初的 400 笔/秒,到今年的 49.1 万笔/秒,这是相当大的跨越。流量的高速增长也给阿里的整个基础设施带来了巨大的压力。
上图是双 11 的一个典型流量表现,零点附近因为有限流,所以看起来是一条平线,零点瞬间飙升到***,并维持在这条线上。
阿里开源了一款 Sentinel 产品,是服务治理限流降级工作的,就是它干的“好事”,虽然有了它能够对流量进行限制,以***程度保障系统不被洪流所压垮,但它也会对业务体验有很大的损失。
于是我们想尽可能的减少这种限制,让大家购物更爽快一些,但这其中遇到了诸多难题,其中包括资源有限的问题。
阿里不仅是只有电商,还包括金融、物流、视频、票务等等,要支撑的基础设施需要的资源是非常庞大的。
巨大的成本压力给我们带来了挑战。如何用有限的成本***化的提升用户体验和集群的吞吐能力,用合理的代价解决峰值?如何持续降低单笔交易成本以提升峰值能力,为用户提供“丝般润滑”的浏览和购物体验?
思路 1:通过云的弹性
我们认为利用云的弹性可以极大缓解短时间使用资源的成本压力。
上图截取了几个月中交易集群的峰值线,***的峰值线是双 11 产生的,第二根是双 12 的峰值线,我们发现双 11 只有一天,过后资源利用率不高,隔年会形成较长时间的低效运行。
因此,我们想到通过公有云的弹性能力来对这一部分的资源进行削峰填谷。大促开始时,借用云,当大促结束后,把过剩的资源还给云。
思路 2:离线混部
由于在线业务需要做容灾,例如建立多个集群等,容量一般都是冗余比较大的,平时电商或者在线服务,CPU 利用率在 10% 左右,除了双 11 或者其他大促之外,流量更多是集中在白天。
目前,进入数据时代的整个离线业务或是大数据计算的增长规模远远快过在线业务。但离线业务资源十分紧缺且资源利用率非常高。
于是,我们考虑平时把一部分的计算任务放到在线这边,就可以极大提高资源利用率;而双 11 时,让离线短暂的降级,便可以借用到大量的资源进行削峰。
云化演进
云化就是让基础设施能够像云一样聚集极高的资源使用弹性能力。思路上主要是上云和自身云化建设这两部分。
达到的成果
我们很多年前就开始做这件事情,这些年下来主要的成果包括:双 11 每万笔交易每年以 50% 的成本下降;核心的混部集群日均利用率可以达到 45% 以上,高峰期可以维持在 60%-70%。
阿里的业务技术演进
在 1.0-2.0 时代,阿里是从 PHP 时代迁移到 Java 的时代,主要面向的是真正的企业级生产。
当它达到了一定规模后,我们开始做了 2.0 向 3.0 时代的升级,主要是单体应用向大型分布式架构的演进。那个时候比较重要的开源项目 Double,就是代表产物。
在飞速发展下,我们现在面临的端口是 3.0 向 4.0 时代的演进,它主要是从单 IDC 架构向多 IDC 架构的云化架构的演进,解决的是成本稳定的问题。
它的体量非常大,线上需要很大规模的资源,如何做好这方面的协同,是我们研究的一个方向。
云化的业务基础
异地多活
多单元化或者云上的方法叫多 Region 化,我们要将其业务部署在多个集群中,但这个工作并不简单,其中存在很多内在关系,我主要从三个方面来叙述为何做这件事情。
***,我们的规模变得极大。例如我们内部一个容器规模在 8 核 16G,在外部大规格的容器下,一个应用可能会达到 1.4 万-1.5 万,甚至是更高的规模体量。
这么大的体量如果放在一个集群规模下,是非常难以管理,并且所有支撑的基础组件,如调度系统、中间件都会出现瓶颈。
第二,容灾。任何程序都有可能出问题,但是如何***程度的在发生线上故障的时候,让损失降到***呢?
最简单的做法就是不要把鸡蛋放到一个篮子里,所以我们做了多单元,当一个单元出问题的时候,就把整个单元下掉,而流量切到其他的单元上。
第三,上云。此外,我们要用云上的资源,而且要用得比较迅速,这时候就需要有一个能力很快把业务完整的搬到云上,用完后再快速的下掉,也就是业界常说的混合云能力,而这个技术就是基础。
异地多活的业务架构
上图是典型的交易单元异地多活的架构。这里面包含普通单元以及中心单元两部分。
通过我们的规模化运维平台,可以做到一键建站,一天内就可以去异地搭建一个新的淘宝、天猫等。
以交易单元为例,现在交易的普通单元,主要处理的一个数据是买家维度。因为卖家的数量在双 11 当天不会突然增加,所以简单来讲,从业务划分、流量切分,主要也是按照买家的 ID 做一个哈希,然后切分。
因为每一个单元的集群能力不一样,流量不一样,所以这里面还有很多的策略。
普通单元主要处理的是买家维度,但商品及库存是需要统一处理的,举些简单的例子,如库存扣减我们目前也是统一到中心单元中进行扣除来防止超卖的情况。
并且卖家维度也是需要一个集群来承担,而中心单元就是承担了这样的责任。
另外中心单元也承担着所有单元交易数据同步的能力,中心单元包涵了所有的数据。
当某个单元出现问题的时候,流量就会先切到中心单元,等单元数据同步完成之后,再切到其余单元。
2013 年的时候,杭州做了 2 个同城单元的验证;2014 年的时候,我们在上海和杭州之间做了 2 个单元。
2015 年的时候,我们建了 4 个单元,另外 1 个单元就是在千里之外的地方。2018 年双 11 有 7 个单元,大家的距离就更远了。
做单元化架构,并不是单元越多越好,这其中是有成本问题的,大家可以看到对于普通单元,也会存在一份全量的库存,卖家等的数据,单元数越多,冗余也越多,同心同步压力也会随之增大。
异地多活的技术架构
异地多活的技术架构,在外部流量过来的时候会有一个统一接入层,这一层会按照用户 ID 标识来进行流量分流。其实我们做的很重要的一件事情就是单元的自闭性。
单元自闭性顾名思义就是一次调用,流量进入到一个单元后,我们希望把所有的服务调用都在这一个单元内处理掉,但这并不完全能做到,有些服务还是需要跨到中心单元调用的,所以***个问题就是路由的一致性。
第二个问题是数据延时,跨城异地多活必然会有延时,网络延时来回就几十毫秒过去了,但这其中涉及到很多的数据同步。
比如中间件的消息同步问题,都可能会产生数据变更不及时的问题,严重了可能引发资损。
***一个问题是数据正确性问题,很多全量数据在数据同步的时候,会发生数据冗余,一旦有数据冗余,数据在便会不一致。我们以前也有一些相关的内部产品 BCP,是专门做数据校验的。
网络虚拟化
多单元的架构后,我们有能力把业务搬上云了,但是网络上如何来互通呢?我们用网络虚拟化来解决数据通信以及隔离的问题。
阿里的绝大部分应用都是跑在 Pouch 容器上的,Pouch 相关的技术也已经开源,而所有容器都是跑在这个层虚拟网络上的,这样既解决了网络互通问题,也解决了网络间的隔离性问题。
初步的混合云架构
2015 年我们完成了混合云架构,当本地保有云无法支撑时,我们就快速在公有云上扩建新的单元,当流量过去后,再还资源给公有云。
我们在集团内部保有云部分,在线服务调度是 Pouch,还有一部分是离线计算任务,目前还是用物理机的模式。
另外一部分是公有云的,我们采用的是 Pouch On Ecs 的方案,打通云上云下的整个运维体系。
对于业务方来说,1.5 万个容器,又分 7 个单元,公有云,保有云运维模式都不相同的话,业务方式肯定要崩溃,所以我们实际上是做了一体化的处理。
云化的资源基础
PouchContainer 容器
上图我们真正建立了组部的混合云 Pouch,Pouch 是云化资源的标准,是云化资源的基础,如果不打通,整个运维复杂性会非常大,在演进之初我们就开始极力推行容器化。
PouchContainer 容器 2011 年就开始建设了,2017 年的时候,PouchContainer 已经开源出来,并达到了百万容器的规模。
2011 年,我们基于 LXC 开始做的时候,只考虑了 Runtime,那个时候觉得物理机比较大,在物理机上部很多应用会比较麻烦,而用虚拟机的模式,Overhead 又比较高。
我们就想到了用容器来解决,当时阿里主要的语言是 Java,Java 语言在运维上是有一些标准的,所以我们没有按照容器即服务的方式建立这个标准。
但是这两年阿里也收购了很多公司,各种语言都会进入到整个的研发体系中,运维复杂度就大大提升了,效率瓶项非常明显。
在 Docker 兴起之后,2015 开始做 Docker 的兼容,把 Docker 好的部分兼容进来,形成了我们的 PouchContainer。
大家知道 Docker 里最重要的一个组件是镜像,但镜像有一个很大的问题就是比代码包的模式要大得多,分发的速度也就慢下来了,而且对于镜像源的压力也是一个大问题。
我们一个应用可能会大到 1.5 万余个容器,如果它的镜像是在同一个源上,这个源马上就会被打挂,再大的带宽都不够。
于是我们采用了开源项目 Dragonfly,它也是刚刚进入 CNCF 项目,通过 P2P 网络来解决这个问题。
Pouch 的演进
对于大公司来说,容器化***的阻碍是历史包袱。我们 2011 年开始做了 T4 容器,那个时候是基于 LXC 做的,但当时为了能够把物理机很好的迁移到 T4 上,我们做了兼容。
T4 上有独立的 IP,能够让 SSH 登陆进去,可以跑多进程,有 SystemD,甚至我们做了可见性的隔离,对于用户来说使用容器还是虚拟机,体验是一致的。
这样的话,我们的升级可以在下层做掉,而对用户来说付出的成本是比较小的,我们把这个称之为富容器技术。
云化的控制引擎
统一调度
只有把容器管理好,整个效率才会高,整个云化才能有更好的效率。于是我们做了统一调度,内部我们在线服务资源调度器称之为 Sigma,离线的计算任务资源调度器称为 FUXI。
FUXI 是我们飞天架构体系当中非常重要的一环。此外,又通过 0 层打通两个调度器,提供一个统一的资源视图和管理器。
Sigma:
- 始于 2011 年,以调度为中心的集群管理体系。
- 面向终态的架构设计;三层大脑合作联动管理。
- 基于 K8S 和开源社区共同发展。
FUXI:
- 面向海量数据处理和大规模计算类型的复杂应用。
- 提供了一个数据驱动的多级流水线并行计算框架,在表述能力上兼容 MapReduce,Map-Reduce-Merge,Cascading,FlumeJava 等多种编程模式。
- 高可扩展性,支持十万以上级的并行任务调度,能根据数据分布优化网络开销。自动检测故障和系统热点,重试失败任务,保证作业稳定可靠运行完成。
什么是混部
把集群混合起来,将不同类型的任务调度到相同的物理资源上,通过调度,资源隔离等控制手段,保障 SLO,极大降低成本,这样的技术我们称之为混部。
在线离线混部:
- 在线优先级高:就像是石块,且延时敏感,利用率不高,不可重跑。
- 离线优先级低:就像水和沙子,且延时不敏感,利用率高, 可重跑。
- 低优先级牺牲:当在线不忙时,离线就抢占,反之则返还,甚至反哺。
- 优先级互补性:是可以进行混部,并带来成本收益的两个前提条件。
混部架构:
- 混部始于 2014 年,2017 在阿里大规模铺开。
- 在线服务长生命周期,定制化策略复杂,时延敏感;计算任务短生命周期,大并发高吞吐,时延不敏感。两边正好产生互补。
- 通过 Sigma 和 FUXI 完成在线服务、计算任务各自的调度,计算共享超卖。
- 通过零层相互协调资源配比做混部决策,通过内核解决资源竞争隔离问题。
- 架构非常灵活,一层之间是共享状态调度,一层之上定制二层调度。
混部的日常效果如下图:
上图是 2017 年的混部日常效果图。2017 年我们做到整个集群混部 45%,非混部大概是 10%,中间有 30% 的提升,2018 年我们已经做到了 45% 以上,峰值可以拉到 60%-70% 以上。
混部肯定是有牺牲的,它对优先级高的业务肯定会有影响,我们把影响做到了 5% 以内,我们可以看到这两条线,一个是混部集群,一个是非混部集,它的 RT 表现影响在 5% 以内。
混部的核心技术
混部的核心技术一方面是调度。通过资源画像,在竞争之前,尽量减少资源竞争的可能性。但竞争永远会发生,因为调度是宏观的数据。
微观上,资源的使用其实是有局部竞争的,所以另一方面,我们在内核上面做了很多的保障,在资源发生极端竞争的情况下,会优先保障高优先级任务,它被动但是延时非常低,毫秒级就可以做出反应。
基于统一 QOS 的调度体系:
- 调度自身 SLO:在线,离线定义自身 SLO 以及和 0 层资源优先级对应映射。
- 资源优先级定义:共同制定 0 层资源优先级等级定义。
- 资源度量及控制:统一度量标准作为 0 层资源控制,调度本身不管是哪种使用资源的策略,但***必须能转换成 0 层的标准度量单位。
日常的分时复用
我们很早就做了弹性的容量托管,但我们发现,只有真正把资源都混合在一起了,才可以把这个资源分时复用的价值放大出来,而这一部分主要节省的是内存资源瓶颈问题。
大促分时复用
上图中上面是我们的日常态,在大促的时候,1 小时之内我们会直接切换成下面的状态,直接把在线的业务、流量都放上来,部署起来形成 1 个大促状态。这个大促支撑了 12 万的交易。
实时的内存超卖
其实在混部中,竞争***的并不是 CPU,因为 CPU 实际上是一个可压缩资源,是有弹性的,但内存是没有弹性的,内存一旦不足,就会 OOM。
这两年大家为了性能的问题,以空间换性能,在内存里放了很多东西,内存资源非常紧张,所以我们会根据实时的内存使用来调整内存的使用水位,我们把这个叫内存超卖技术。
在内存这块,目前还有一些***的研究方向,比如如何更好的管理 Pagecache 等。
存储计算分离
存储计算分离是我们做混部时遇到的***个问题,因为大数据需要很大的计算资源、需要很大的磁盘,而在线应用需要的磁盘很小。
原先的时候我们都在一个物理机上,根本没有办法调度,所以我们把计算和存储做了分离,把原来统一的资源拆分成了计算节点与存储节点。
这样就能更好的控制存储的性能与容量问题,让成本保持***,不过这个方法会对网络有较大的依赖。
内核隔离
我们最终形成了一整套混合云的体系。我们将所有的业务在上层进行混合部署,下层既可以是在线的独立集群,也可以是混合部署的集群。
还可以是计算业务独立的集群,甚至也可以是 ESC 上面的集群,公有云的这些集群,形成上图的架构体系,所有资源层都可以打通,形成混合云模式,共同来支撑起阿里巴巴的业务。当然最终的目标是完全转化到公有云上。
云化的未来展望
目前我们研究的方向很多也很杂,文章上述提到了几个阶段:
- 微服务化,主要解决的是人与服务的协同。而最复杂的是服务与服务的协同,也就是我们常说的服务治理。
- 云化架构我们认为是人与资源的协同,而最难的是资源和资源的协同,比如像单元化,混部等。
- 我个人认为未来的一个方向是业务与资源的协同,也就是用户不再需要关注资源,关注运维,只要把业务要求以标准形式输入就可以了,系统自动会以***的策略进行部署。要做到这些,可以采用业界炒得比较火的 Serverless 的模式,其中的关键是打通业务与资源中间的标准。
吕奇,花名潇谦,阿里高级技术专家。10 多年的老程序员,2014 年加入阿里巴巴,是阿里巴巴大规模混部及容器化的项目负责人,4 次参与双 11 大促,目前主要负责阿里巴巴集团内的规模化混部、虚拟化、存储与日志中心等。