阿里研究员蒋江伟谈双11容量规划8年历程,全链路压测是未来 - 阿里技术
近期在ArchSummit北京上,阿里巴巴研究员蒋江伟(花名小邪)发表了《天猫双11容量规划演进》主题演讲。主要介绍了阿里巴巴从09年开始,为了解决大促过程中资源精确准备而进行的容量规划工作,在这一过程中阿里的容量规划经历了多个版本的演进,比较好的解决了分布式架构下的系统容量评估问题,通过压测确定系统的基准吞吐量,找到集群的短板,快速找到特定场景下的集群服务器配比和每个系统支撑该场景所需服务器的数量。通过阿里巴巴技术架构的统一性,将这一成果很好地平台化,迅速普及到集团所有业务场景。
演讲全文:
大家好!做了很多年的天猫双十一,从2009年开始一直到2016年都参与了其中。先说一下09年,09年参与了但是没有什么感觉它就过去了。主要原因是什么?主要原因是当时整个淘宝的体量太大了,就是每天的交易额已经有几亿的规模,当时做淘宝商城,那时候还不是天猫,是淘宝商城,09年的双十一交易额只有5000万,5000万和好几亿比体量还是非常小的,所以还没开始就过去了。
到了后面几年,其实在这几年每年都要花费好几个月的时间去精心的准备,要做报警的梳理,要做流量的规划,要做整个治理等等,也整理了各种各样的方法论,这是一个过程。当然在这个过程里面也沉淀出了很多非常有意义的事情。今天如果有人问我怎么做双十一,怎么做大促活动,我会告诉他一个非常简单的方法,就是做好流量规划,做好限流降级。
我自己是在08年的时候加入淘宝,当时是直接就参与到淘宝商城的研发工作中去。淘宝商城就是后来的天猫,当时整个淘宝商城的技术体系跟淘宝网是完全不一样的,它是完全独立的体系,包括它的会员、商品、营销、推进、积分、论坛,都跟淘宝网没有任何关系,两套体系是完全独立的,惟一有关系的是整个会员的数据是共享的。
08年之后我们做了一个五彩石项目,就是把两套体系的数据和业务打通。首先,这个项目做完之后,给淘宝商城也就是后来的天猫的发展,带来了非常大的飞跃,就是后面速度发展非常快了,品牌也得到了升级。第一呢,这个项目里有一个很重大的意义,就是通过架构的扩展性达到了一个业务的扩展能力。在08年的时候,我们实现了整个服务的全部服务化,抽取了所有的跟电商相关的公共元素,比如说我们把会员体系、商品中心、交易中心、营销、店铺、推荐等等中心都抽取出来,基于这个体系,构建后来的像聚划算等等的业务就非常的快。这就是打破了原来的架构,把整个公共服务给抽取出来之后,让上层的业务跑得非常快,所以这解决了业务扩展性的问题;第二就是技术的扩展性,在这个项目里第一次大规模使用了中间件,所以也带来了技术的进步。总的来说,整个五彩石项目从业务的发展以及技术的扩展性,都达成了非常好的目标。
在2012年的时候,我开始带中间件团队,我们讲为什么要做容量规划?回过头来看这个问题,容量规划也算是双十一这个过程中非常好的创新,双十一推动了阿里巴巴技术上非常大的创新,我今年做双十一的时候,有个老板问今年有什么风险?风险肯定有很多,但是最终如果我们的系统出问题了,我想肯定是出在在交易系统。我们系统分两部分,一部分系统就是促进交易效益的,比如推荐、导购、搜索,还有一些频道都是来促进交易的,他们会做各种各样的营销,这样的系统就是的导购系统;另外的系统负责交易,就是交易系统。导购系统你准备得再不充分,我相信它也不会出问题;但是你交易系统准备得再充分,它肯定还会出问题。原因非常简单,因为导购类的系统是留给你足够的时间去做判断的,因为它流量的上涨不是瞬间上涨,它是慢慢上去的,它是一个曲线,它留给你30分钟判断时间;而交易系统不会给留时间给你判断,一旦流量开始,你没有反应时间,你也没有任何决策时间,所有的行为只有系统会自动化执行。这个过程里面提前做好容量规划非常重要。
我们在早些年的时候,那时虽然没有做双十一,但整个业务的自然增长就非常非常快。我印象非常深刻的是,当时我们有个页面,就是大家购物的时候打开的那个商品详情页面,打开的人多了之后,有一段时间它的负载比较高,公司就召集了一帮做性能优化的人去分析,去解决,调优了几天之后系统终于还是挂掉了;同时我们也在做另外一些准备,我们做了一些服务器的扩容的准备,后来就是把服务器扩上去,重启之后负载高的问题就解决了,这是一个事情。
这件事情说明了什么?在早些年的时候,其实淘宝网也是一样,天猫对容量的准备和预估是没有概念的,不知道多少容量能支撑整个系统,需要多少的能力,大家是没有这个概念的。新业务也是不断的上线,包括促销类的活动也非常频繁。有一次做一个比较大的促销,规模非常大。首先说一下我们的会员系统,当时这是我们非常非常重要的系统,所有的业务基本上都会访问这个会员中心的用户数据,包括买家的数据还有卖家的数据,这个系统的单机缓存能力在当时的规模,大概是在每秒处理8万的请求,在今天来看是远远不止,当时高峰期还没来临的时候就到了每秒6万的请求。我们就把所有的访问会员系统的都拉出来,然后去看哪些是跟交易无关就全部停掉,或者停掉一半,当时开心网比较流行,我们也做淘江湖,这个时候我们只能将它关停掉,我们当时确实做了这样的事情。在这个过程里面我们发现了各种各样的问题,其实一句话,就是我们根本不知道这个容量怎么去做,或者根本就没有这个概念要去做。归结起来,就是在什么时候什么样的系统需要多少服务器,这个需要有确定性,而且需要有个量化的数字能够给出来。
容量规划这个事情,整个过程大概经历了7-8年的时间,第一个阶段就是非常早期的阶段,我们当时的评估手段就是拍脑袋,就是根据一些负载情况,系统响应时间等各种各样的表现去拍一个数字出来。比如说当时我问一个技术高管,我们一台服务器是怎么去判断是不是够负载够高,要支撑多少流量?他告诉我一个经验值,你每台服务器支持100万的PV。下面这个流量曲线是当时一天的流量曲线,会有三个峰值,早上九点到十点,中午两三点到五点,晚上八点到十点之间都是峰值。为什么说是100万呢?这就是一个经验值,我们希望做到一半的服务器停下来之后去做发布,这个时候能够去支撑线上的流量,同时我们要看峰值的情况下,我们全部能够支撑住。这样去算的话,实际上单机支撑是320万的PV,这是一个当时的经验值。
当然这个经验值是有效的并起作用的,原因是当时的系统架构相对简单,你可以理解为把整个淘宝所有的逻辑和模块都集中在一个系统里面,所以各个模块之间的热点是有时间差的,这个时间差可以让系统的资源被充分利用服务器可以自己调度来各个资源的分配。后面到了第二个阶段,系统进行了分布式改造,这个时候就会出现问题,以前会员的调用和交易的调用都是在一台服务器上,交易处理需要调用会员的信息,系统分开之后,交易系统和会员系统之间调用其实是有一个比例的,比如1次交易要10次会员的调用,这个比例是多少?当系统多了之后这个比例是比较难搞清楚的,所以必须要引入一些压测机制。 总结一下:第一阶段就是什么都没有,就是拍脑袋;第二个阶段引入压测机制,像一些商业的压测工具我们也引入进来了。当时有两个目的,第一个是我们的系统上线之前要做压测,你的响应时间,你的负载要能够达到上线的要求;第二个目的,希望我们能够根据线下的压测情况,能够准确的评估出线上大概需要多少服务器。第二个目的是怎么也达不到,我记得当时性能压测团队还做了一个项目,我记得叫做线上线下容量的关系,做了这些事情其实没有任何结果。因为大家可以想一下,线上的环境和数据和线下完全不一样,这里面没有规律可寻,你没办法通过线下压测的指标能反馈到线上去。这时候怎么办?我们又换了一下思路,直接在线上压测,当时来看这个决定非常疯狂,因为没有一家公司,包括阿里巴巴之前也没有人在线上直接做压测。我们直接选了一些工具,通过前一天的日志大概拉出所有的日志做回访,直接在线上做,压出来之后其实可以知道每个系统大概的一个容量需求,比如说根据它的响应时间和负载设定一个的阀值,看它的QPS多少,然后把它做出来。
第二件事情我们做了一个分流压测,系统架构全部是基于一整套的中间件,所以只要简单的通过软负载调整服务器的流量配比,就可以实现单机单系统的容量评估,简单点说就是把线上的流量调整到一台服务器上,通过调整应用端或者服务端的流量配比,增加服务器的流量的权重,这时候它的负载和QPS也会上升,我们把这个过程记下来。这里已经是两种场景了,一种是回放日志,这是模拟流量进行压测;第二种是一种真实的流量压测,我们让它每天线上跑并产生数据。这个事情做完之后意义很明显:替代了线下性能压测的过程,因为它可以让每个系统每天能够跑出来它的数据情况,比如实际生产中性能表现情况,比如某个项目发布有没有影响它的性能等等,这些指标都可以看出来。。
第三个,做到这里,我们发现这里面其实还有个问题,那就是它没有基于场景化。比如我买件衣服,在平时我买东西的流程可能是从购物的搜索框里面搜索,或者是从一些类目的导航里搜索,从搜索再到购物车,再到下单。双十一推的商品具有确定性,很多的频道会把卖家比较好的促销的商品直接拿出来,作为一个频道页;而双十二的时候推的是店铺,KPI不一样,因而推的东西也不一样。比如说双十一商品相关的服务器系统流量会高,它所需要的服务器也会更多一些。双十二的时候就是跟店铺相关系统的服务器需要会更多一些。它跟你平时的流量表现是不一样的,你用平时的流量去计算你的场景化流量,这也是不准确的,所以接下来我们又做了下面这个事情,就是场景化的压测。
场景化压测,这是在我们从2013年开始做的事情,就是之前都没有对外讲过的核武器。09年是最顺利的一次双11,但是没有什么流量。10年、11年、12年,其实这三年的双11总是有些问题,那就是心里没底。就像刚才讲到了,其实峰值的时候,你没办法得出做出响应的这么一个临界点。当然在13年的时候,我们做了这个场景话压测之后,有了一个本质的变化,13年的表现非常的好,包括14年也非常好,这就是我们内部称之为核武器的场景化压测。这个对于营销和促销类的活动,就是那种有峰值的,在这个时间点之前峰值非常低,这个时间点之后峰值突然上去了的场景,这种压测是非常有效的一种方法。
下面重点讲一下线上压测和场景化压测。首先,淘宝的业务形态多样化,它的各种各样的业务那个时候都起来了,因为它解放了生产力,以前100多个人在一个系统里开发,那时候非常糟糕,通过分布式改造之后,整个业务服务抽象出来之后整个生产力被解放了。第二,每个业务的机器规模也是非常大,每个业务应用数量也非常大,我们怎么做呢?其实是做了一个分层,我们的一个标准就是说,我们根据一个系统它具备的容量,然后去不断的计算,最后通过把整个集群,阿里巴巴的集群容量给计算出来,我们先做这么一个应用系统,通过分流,通过负载均衡把流量导入之后,把它的负载加到最高之后计算出来,之后把这个应用的整个集群,比如100台服务器,它能够支撑多少量计算出来。再计算整个服务,服务也可以做分流,把服务计算出来,一层一层计算,当然数据库非常难算,数据库都是提前规划的,因为一般来说数据库分库分表做好之后,都是留了两几年的量,这个确实比较困难一些,但是缓存是可以做的。
通过刚才说的办法把整个集群的量和规模全部计算出来,但是算出来之后它是有问题的,为什么呢?因为系统一旦开始拆了之后会一发而不可收拾,会拆得越来越多。我们虽然有工具能够把它梳理出来,但是你没有精力看,到底哪些系统在这个场景下面因为什么原因导致整个集群出现了一个小问题,一旦出现了某个小问题,会导致整个集群全部崩溃掉,这种问题是没法避免的。但是在13年之前我们都是基于这套体系去做的。想想当时这么做也是挺合理的,就是每个系统我都能算出它的容量,我通过一个一个集群算出来整个大集群的容量也是可以的,但是它还不是一个非常好的解决方案。但它非常好的一点是,这个工作可以自动化运行,可以让它每天去跑,跑出我们系统的一个容量,并且可以保证系统不腐化,就是日常的一些性能、指标不腐化,这是在线压测整个架构图:(下图)
我们就是通过几种方式,模拟、流量的复制,转发的引流,还有负载均衡的流量,通过这种机制去做在线压测。我们整个系统全部是做成自动化的,每天都会去跑,准确的讲每周都会跑。根据发布前后的一天跑这个数据,跑出来之后生成一个报表去反馈,看性能有没有下降,根据这个计算值去准备整个活动,整个流量大概要多少。这个ppt有一些数据,每天自动做压测,这种效果和效率靠人工做性能压测是做不到的。
所有的这些它都是以点到面,通过一个个点的容量评估,扩展到一条线,扩展到一个面,最大的问题是没有个人搞得清楚整个架构到底怎么样,是不是有遗漏,整个系统依赖关系里面如果有遗漏,之后会形成整体的崩溃。
另外,我们需要场景化的压测是因为整个背景流量太低,压力不够,在线压测的这个流量大部分用的是分流,分流意味着他是用真实的流量去做的,他不会有数据上问题,但是流量其实是很低的,和做活动相比流量非常非常低。背景流量不够大,整个网络以及网络设备,包括一些交换机的流量是跑不满的,所以有些问题在没有流量压力的情况下是没办法暴露出来的。还有一个就是每一个场景化的确定性,每个购物流程是不一样的,我需要确定的是,在不同购物流程的场景下面我要把整个系统的资源能够确定下来,用最少的服务器支撑最大的量,我需要把它确定下来。
怎么做场景化压测这个事情呢?当时我们内部有一些争论。第一种方法就是搞一个小流量的环境,比如说把淘宝网隔离出一个小的环境,里面布了100多个系统,但是它环境比较小。整个流量引进来,把整个小环境里的集群跑满,流量跑满。这么做能够解决什么呢?我觉得它比较好的解决了系统的依赖关系的问题,如果我一个依赖出现问题的时候,我的上下游依赖出现问题的时候,在这个环境是能够印证的,但是没办法解决的是环境的问题,环境上出现一些问题你是没办法解决的。
当年就有这么一个业务,就是采用了整个一种类似于小环境的流量去验证,导致他的入口的交换机的整个流量跑满。所以说我们需要有一个更加强大的性能评估工具。这就是基于场景化的容量压测,在2013年之后我们全部基于这套体系在做。做场景话容量压测,第一个就是要造数据,因为它的流量全部是造出来的,造出来的场景是需要有一个接近度,我们希望能够更接近真实的情况。刚才讲的临近峰值你是没办法做决策的,你惟一能做的就是提前模拟一次峰值。我们把整个流量模拟出来,在这样的流量压力下你的集群能够表现出什么样子,这是一个理想的架构,但它也有很多困难的地方。我们尽可能把数据造得精确,各种场景都要模拟出来,购物车里面的商品比例是多少,一次下单有多少商品,最后多少商品提交到支付宝,这些场景都要模拟出来。这个造出来的数据量这几年越来越大,以2015年为例,这个数据量接近一个T,我们把这一个T的数据传到我们的中心,通过中心传到我们的压测集群上面去,它可以产生非常巨大的流量,这个流量可以和双11一模一样的,之后再传到CDN的节点上面,产生巨大的流量。
这里还有一个技术点,就是压测工具要支持多种协议,还有一些性能提升工作也是要做的,另外还要做流量控制,就是要能够做到快速调节,因为这个业务场景在压测的时候有人会提出来说,你需要将流量做一些调高或调低。这是一个压测流量,右边这个图是我们真实的流量,因为这些全部是在线跑的,它没办法在线下模拟这个环境,全部都是在线上跑的,会影响线上的正常的流量,所以你需要的流量的染色,把正常的流量和压测的流量完全区分开来。
第四点还要做流量的隔离,在没有流量隔离之前,当时我们怎么做呢?我们只能凌晨做,零点以后流量很低的时候,我们坐满人,有人说开始,然后整个流量就起来了,所有的人都盯着自己的系统,看有没有出现什么问题,所以当时大家都非常辛苦。第二年大家提了一个目标,能不能改善一下大家的幸福指数,然后我们就做了一个流量隔离的工作。流量隔离就是快速地通过负载均衡和中间件,从原来在线的集群中隔离出一个无流量的集群出来,当然隔离出来这个集群的规模是非常大的,它可以占比原来的10%到90%都可以。比如原来有10万台服务器,我可以将其中9万台服务器全部隔离成一个集群。因为准备做大促的时候,像双11的流量是平时峰值的20倍以上,所以它的平时流量非常低,你是可以把它给隔离出来的,并且不会影响现有的流量,所以做了一个隔离的系统。整个过程怎么样呢?举的例子,我们ABCD这4个系统,场景1是日常的流量,我们今天要做的活动则会是场景2的情况,我们通过压测之后发现ABCD的流量配比是这样的,原始的场景C所需要的服务器多,但是我们压测出来之后发现,在做活动的时候B和D所需要的服务器比较多。压测出来之后整个过程都是自动化,就是可以你达到多少量的时候,如果是C这个系统不需要这么多的服务器,它的服务器就会被下线,下线之后这些服务器就被自动加到D。这些过程都是自动化运行的,整个效率都非常高,而且不一定要在凌晨才能运行。最后我们把ABCD整个比例压出来之后,得到结果和数据后,所有的资源还是还回去的,把整个隔离出来的集群再还到原来的在线集群,最后变成ABCD这样流量的比例,就是服务器的比例,这样你就可以准备第二天的大考,做这样的大促活动了。
整个容量评估的流程,我们有一个指挥部,我们要做一次活动,我们在系统里面输入一个数值,比如说这次活动我们大概要实现5万笔每秒的交易量,我们输入5万笔每秒这个数字之后,整套系统开始运作,开始做压测,开始做弹性调度,然后做隔离,然后去压测,最后就是把整个环境做好,就是5万笔每秒的环境就还给你了,这就是整个自动化的过程。
整个容量是可以预测的,但是它是没办法规划的,我们可以非常精确的预测出来双十一大概会来多少流量,会来多少用户,以及当时的峰值会有多高,这是可以完全精确的预测出来,这也没有太多的意义。我们就是限流了一个笔数,我们就卡在那里,整个流量就在那里,所有的系统先导入这个值,整个比例按这个来配,这也是没有办法的办法。因为它真实的流量比这个大得多,你要支持真实的流量你的成本会非常高。虽然整个系统都是基于阿里云,整个成本带来了非常大的下降,日常我们所有的服务器数量是非常低的,在大促的时候基本上都是采用阿里云服务器,所以成本下降非常大。所以说整个容量规划的工作首先就是先限定了一个值,比如说今年是17万,明年可能是20万或者25万,我们在这个限定值的基础上,我们通过基于场景化压测工具,然后把整个系统的容量给计算出来,把整个处理器拉平,我们用了最少的资源去做了一次最成功的活动。没有一个系统的服务器会被浪费的,什么系统所备服务器是过多或者过少,在这个过程里都会被识别出来,所以是这么一个过程。
从2013年开始,我们通过这套技术发现了大量的问题,而这些问题你在使用普通测试,比如日常测试,功能测试,或者一些工具测试,你是没办法发现这些问题的。这些硬件的、网络的、操作系统的,从来没有发生过的各种诡异问题,在大负载情况下都会被发现。如果一个问题在双11的时候发生,可能就是灾难性的。13年的时候,我们在做完这些事情之后,回头看12年、11年,这几年不出问题才怪,肯定百分之百出问题。凡是这种峰值流量是你平时流量多少倍以上的活动肯定会出问题,因为很多的问题是没办法通过一些逻辑,通过一些思考你把它给找出来的,它必须借助一个真实的环境,模拟出所有场景的流量把它给引出来,只有这样才能够做到。
总结一下,从整个过程来看,容量规划其实是一个领域,在这个过程里面,利用商业软件去做性能压测,当时我们觉得这个软件应用挺好的,也是能够支撑我们的整个容量的一些计算,甚至今天我们了解到很多外面的公司还在用类似的软件做性能评估,当然这些软件也是不断演进的。但是我们后来发现,其实你跟真实压测评估的容量还是相差非常远,所以我们引入了线上的压测,引入了分流、复制流量、还有日志回放,通过一个个节点把自己的流量精确地评估出来。当时我们做了这套系统觉得很牛,当年也获得了整个技术部的创新大奖。觉得有了这套系统之后我们做双十一就不用愁了,做任何活动都不用愁了,觉得这是非常了不起的系统。实际发现我们还是需要不断的发展,做了一个全链路压测,在整个链路上我们基于真实场景化的模拟,把整个集群能够压测出来。回过头来看就是这么一个过程,其实很多时候在一个领域里面,当自己满足于当前现状的时候,其实你还是可以继续往前走一步。
最后总结一下,双11技术创新有很多,容量规划只是其中一个点,另外还有非常重要的一点我想说一下,阿里巴巴整个技术架构非常统一的,我们做了全链路压测之后,很多其他业务单元,像支付宝等等都可以采用这种方式做,因为它的技术体系基本上是和阿里一致的,所以容量规划可以非常简单的被复制出去。我看过整个阿里巴巴的技术体系和架构,无论是下面的分布式架构也好,还是上面的服务化架构也好都非常统一,这也给我们带来了非常好的成本优势。从研发过程以及学习的过程,以及运维的过程,所需要的成本都非常低。所以我们整个团队非常少的人就能完成全链路压测,也就是4到5个人,但是却能够服务了整个集团100多个业务方,这都是因为整个架构的统一性所带来的宏利。
今年的双11做完之后,我们的CTO也给我们提出了新的挑战,他觉得双十一的整个过程,效率能够更高,从自动化演进到智能化,不断提升利用数据来做运维决策的比例,比如发生一个故障,要能自动给出整个系统链出问题的概率分布,可能是A系统导致的问题的概率10%,网络链路概率30%等等,然后要越来越精确,挑战很大。