从 2009 年开始,阿里双十一就成了流量最大、成交额最高、业务场景最复杂的电商大促活动。曾在 2011/12 年给淘宝技术团队留下惨痛回忆的大促活动,也倒逼阿里技术人员加强对大促环节的加持。容量规划、全链路压测,这是阿里应对大促环境的两大法宝,怎么作的?web
SREcon 是由计算机科学领域知名机构 USENIX 主办,聚焦网站可靠性、系统工程、以及复杂分布式系统相关的运维行业技术盛会,今年 SREcon17 大会 Asia/Australia 站于当地时间 5 月 22 日 -24 日在新加坡举行。吸引了来自 Google、Facebook、微软、阿里巴巴、百度和滴滴等全球著名互联网科技公司的顶级技术专家,到会分享网站可靠性工程相关的议题,包含大规模网站可用性提高、资源规划及性能优化等话题。算法
写在前面数据库
双十一从 2009 诞生到如今,2013 年绝对是一个分水岭。apache
为何这么说?由于 2013 有了全链路压测。缓存
每一年的 11 月 11 日 00:00:00,阿里巴巴集团最紧张激动的时刻到来了。多收档的热情这一刻开始爆发,反映到数字上是去年双十一今人的记录:24 小时交易额 1012 亿,交易建立峰值 17.2w;而在二进制世界里面,则是极短期内如海啸般涌入的超大规模流量。安全
流量洪峰的杀伤力,曾在 2011 年和 2012 年给技术团队留下了午夜惊魂的难忘回忆。然而随着全链路压测的登场,它改变了阿里巴巴对应流量洪峰的态度和方式,也一次次刷新中国互联网世界的纪录。性能优化
为何须要容量规划?架构
阿里巴巴有着很是丰富的业务形态,每种业务都由一系列不一样的业务系统来提供服务,每一个业务系统都分布式地部署在不一样的机器上。随着业务的发展,特别是在大促营销等活动场景下(好比双 11),须要为每一个业务系统准备多少机器对于阿里巴巴技术团队来讲是一大难题。“容量规划”正是为解决这个难题而诞生,容量规划的目的在于让每个业务系统可以清晰地知道:何时应该加机器、何时应该减机器?双 11 等大促场景须要准备多少机器,既能保障系统稳定性、又能节约成本?负载均衡
容量规划四步走框架
在双 11 等大促场景的准备过程中,容量规划通常分为四个阶段:
业务流量预估阶段:经过历史数据分析将来某一个时间点业务的访问量会有多大;
系统容量评估阶段:初步计算每个系统须要分配多少机器;
容量的精调阶段:经过全链路压测来模拟大促时刻的用户行为,在验证站点能力的同时对整个站点的容量水位进行精细调整;
流量控制阶段:对系统配置限流阈值等系统保护措施,防止实际的业务流量超过预估业务流量的状况下,系统没法提供正常服务。
在第一个阶段当中,经过合适的预测算法和丰富的历史数据,一般可以比较准确地预估业务的访问量。即便在第一阶段预估的业务访问量跟实际的存在偏差,经过第四阶段的流量控制也可以确保站点始终处于良好的服务状态。作完业务访问量的预估以后,容量规划进入第二阶段,为系统进行容量的初步评估。如何经过精准的容量评估,用最小的成原本支撑好预估的业务量是这个阶段的核心问题。
要计算一个系统须要多少台机器,除了须要知道将来的业务调用量以外,还有一个更重要的变量,就是单台机器的服务能力。获取单台机器的服务能力在阿里巴巴是经过单机压测的方式来获取。在阿里巴巴,为了精准地获取到单台机器的服务能力,压力测试都是直接在生产环境进行,这有两个很是重要的缘由:单机压测既须要保证环境的真实性,又要保证流量的真实性。不然获取到的单台机器服务能力值将会有比较大的偏差,影响到整个容量规划的准确性。
生产环境进行单台机器压力测试的方式主要分为 4 种:
模拟请求:经过对生产环境的一台机器发起模拟请求调用来达到压力测试的目的
模拟请求的实现比较简单,也有很是多的开源或者商业工具能够来作请求模拟,好比 apache ab、webbench、httpload、jmeter、loadrunner。通场状况下,新系统上线或者访问量不大的系统采用这种方式来进行单机压测。模拟请求的缺点在于,模拟请求和真实业务请求之间存在的差别,会对压力测试的结构形成影响。模拟请求的另外一个缺点在于写请求的处理比较麻烦,由于写请求可能会对业务数据形成污染,这个污染要么接受、要么须要作特殊的处理(好比将压测产生的数据进行隔离)。
复制请求:经过将一台机器的请求复制多份发送到指定的压测机器
为了使得压测的请求跟真实的业务请求更加接近,在压测请求的来源方式上,咱们尝试从真实的业务流量进行录制和回放,采用请求复制的方式来进行压力测试。请求复制的方式比请求模拟请求方式的准确性更高,由于业务的请求更加真实了。从不足上来看,请求复制一样也面临着处理写请求脏数据的问题,此外复制的请求必需要将响应拦截下来,因此被压测的这台机器须要单独提供,且不能提供正常的服务。请求复制的压力测试方式,主要用于系统调用量比较小的场景。
请求转发:将分布式环境中多台机器的请求转发到一台机器上
对于系统调用量比较大的场景,咱们有更好的处理办法。其中的一种作法咱们称为请求的引流转发,阿里巴巴的系统基本上都是分布式的,经过将多台机器的请求转发到一台机器上,让一台机器承受更大的流量,从而达到压力测试的目的。请求的引流转发方式不只压测结果很是精准、不会产生脏数据、并且操做起来也很是方便快捷,在阿里巴巴也是用的很是普遍的一种单机压测方式。固然,这种压测方式也有一个前提条件就是系统的调用量须要足够大,若是系统的调用量很是小,即便把全部的流量都引到一台机器,仍是没法压测到瓶颈。
调整负载均衡:修改负载均衡设备的权重,让压测的机器分配更多的请求
与请求引流转发的方式相似,最后一种压测方式一样是让分布式环境下的某一台机器分配更多的请求。不一样的地方在于采用的方式是经过去调整负载均衡设备的权重。调整负载均衡方式活的的压测结果很是准确、而且不会产生脏数据。前提条件也须要分布式系统的调用量足够大。
在阿里巴巴,单机压测有一个专门的压测平台。压测平台在前面介绍的 4 种压测方式基础上,构件了一套自动化的压测系统。在这个系统上,能够配置定时任务按期对系统进行压测,也能够在任意想压测的时间点手动触发一次压测。在进行压测的同时,实时探测压测机器的系统负载,一旦系统负载达到预设的阈值即马上中止压测,同时输出一份压测报告。
由于是在生产环境进行压测,咱们必须很是当心,保障压测过程不影响到正常的业务。在单机压测平台上,每月将进行 5000 次以上的压测,系统发布或者大的变动都将经过单机压测来验证性能是否有变化,经过单机压测获取的单机服务能力值也是容量规划一个很是重要的参考依据。
有了预估的业务访问量,也知道了系统单台机器的服务能力,粗略的要计算须要多少台机器就很是简单了。
最小机器数 = 预估的业务访问量 / 单机能力。
一般状况下,咱们会预留少许的 buffer 来防止评估的偏差和意外状况。
为何须要全链路压测?
进行到这一步,咱们已经完成了系统容量的粗略评估,然而作到这一步是否是就够了呢?过去的教训曾经狠狠地给咱们上了一课。
咱们对每个系统都作好了粗略的容量计算,觉得一切都会比较顺利了,但是真实场景并不是如此,当双 11 的零点到来的时候,许多系统的运行状况比咱们想象的要更坏。缘由在于真实的业务场景下,每一个系统的压力都比较大,而系统之间是有相互依赖关系的,单机压测没有考虑到依赖环节压力都比较大的状况,会引入一个不肯定的偏差。这就比如,咱们要生产一个仪表,每个零件都通过了严密的测试,最终把零件组装成一个仪表,仪表的工做状态会是什么样的并不清楚。
事实上咱们也有一些血的教训。在 2012 年的双 11 零点,咱们一个系统的数据库的网卡被打满了,从而致使部分用户没法正常购物,尽管当时咱们作了很是充分的准备,但还有一些事情是咱们没考虑到的。
须要怎么样才能解决这个问题?在 2013 年的双 11 备战过程中,在很长一段时间内这都是咱们面临的一个难题。在中国,学生一般都会有期末考试,为了在期末考试中取得比较好的成绩,老师一般会让学生们在考试前先作几套模拟题。双 11 对咱们的系统来讲就是一年一度的期末考试,因此咱们冒出了这么一个想法:“若是能让双 11 提早发生,让系统提早经历双 11 的模拟考验,这个问题就解决了”。经过对双 11 零点的用户行为进行一次高仿真的模拟,验证整个站点的容量、性能和瓶颈点,同时验证以前进行的容量评估是否合理,不合理的地方再进行适当的微调。
咱们为此研发了一套新的压测平台——“全链路压测”。双 11 的模拟可不是一件简单的事情,上亿的用户在阿里巴巴平台上挑选、购买好几百万种不一样类型的商品,场景的复杂性很是高。有三个最主要的难点须要解决:
用于的请求量很是大,在双 11 零点,每秒的用户请求数超过 1000w;
模拟的场景要跟双 11 零点尽量的贴近,若是模拟的场景跟双 11 零点差距太大,将不具有实际的参考价值,而双 11 零点的业务场景很是复杂;
咱们须要在生产环节去模拟双 11,如何去作到模拟的用户请求不对正常的业务和数据形成影响。
为了可以发出每秒 1000w 以上的用户请求,全链路压测构件了一套可以发出超大规模用户请求的流量平台。流量平台由一个控制节点和上千个 worker 节点组成,每个 worker 节点上都部署了咱们本身研发的压测引擎。压测引擎除了须要支持阿里巴巴业务的请求协议,还须要具有很是好的性能,要否则 1000w 的用户请求,咱们将没法提供足够多的 worker 节点。上千个压测引擎彼此配合、紧密合做,咱们能像控制一台机器同样控制整个压测集群,为所欲为的发出 100w/s 或者 1000w/s 的用户请求。
1000w+/s 的用户请求量不只要可以发送出来,并且还须要跟双 11 的用户行为尽量的接近,而双 11 是一个很是复杂的业务场景。为了使得模拟可以更加真实,咱们作了很是多的工做。首先,咱们从生产环境提取一份跟双 11 同等数量级的基础数据(包含:买家、卖家、店铺、商品、优惠等等),作好筛选和敏感字段的脱敏,做为全链路压测的基础数据。而后基于这些基础数据,结合前几年的历史数据,经过相应的预测算法,获得今年双 11 的业务模型。
双 11 的业务模型包含 100 多个业务因子,好比:买家数量、买家种类、卖家数量、卖家种类、商品数量、商品种类,pc 和无线的占比,购物车里的商品数量,每一种业务类型的访问量级等等)。有了业务模型以后,再根据业务模型构造相应的压测请求,最终将压测请求上传到压测引擎。
全链路压测直接在生产环境进行双 11 的模拟,在前面的单机压测方式中也有提到,对于模拟请求的方式,须要考虑脏数据的处理方式。全链路压测的全部数据都在生产环境作了数据隔离,包含存储、缓存、消息、日志等一系列的状态数据。在压测请求上会打上特殊的标记,这个标记会随着请求的依赖调用一直传递下去,任何须要对外写数据的地方都会根据这个标记的判断写到隔离的区域,咱们把这个区域叫作影子区域。全链路压测对粗略的容量评估起到了精调的做用,使双 11 零点的各类不肯定性变的更加肯定。
咱们在 2013 年双 11 前夕的全链路压测过程中共发现了 700 多个系统问题,201四、201五、2016 一样也发现了好几百个问题。这些问题若是没有在全链路压测的过程中被发现,颇有可能会在双 11 零点的真实业务场景当中暴露出来,将形成严重的可用性影响。
超限后的流量控制如何作?
前面章节咱们讨论的都是”容量规划”,咱们知道容量规划是基于一套精密的业务模型,而这个业务模型是根据历年来的大促数据,以及复杂的预测模型推算出来的。然而,不论这个模型多么强壮,它始终是一个预测。这就意味着咱们存在着预测和现实流量有偏差。
这个并不只仅是一个担忧,这个发生过很是屡次。最近的一个例子是在 16 年的双 11,咱们为某一个重要的场景预备了足以应付 16.2 万每秒的峰值,然而那天的峰值实际上到达了 20 万每秒,超过咱们准备能力将近 13%,你可能以为这只会对峰值产生影响,这些额外的 2W 请求立刻就会被消耗掉,但并非你想的这样。
当一台机器超负荷运转的时候,这台处理请求的时间会变长。这会给用户带来很差的体验,用户会试图重复提交请求,这无形中又给系统带来了更多的请求压力。随着请求堆积的愈来愈多,系统性能会逐渐降低甚至没法响应新的请求。
当一台机器挂掉之后, 负载均衡会把请求重定向到另外的机器上去,这又无形中给别的机器带来了更多的任务,而这些机器也处于一个饱和的状态,很快也会像第一台机器同样,也没法响应新的请求。就这样,在很短的时间以内,愈来愈多的机器会中止响应,最终致使整个集群都没法响应。这就使咱们经常说的“雪崩效应”。一旦“雪崩”发生,就很难中止。咱们必须有一个有效的机制,来监控和控制进入的流量,来防止灾难的发生。
然而,流控并不只仅用于流量高峰,它在不少的场景均可能用的到。好比在一个业务的链路上,有一个下游系统出现了问题,响应时间变得很长。这个问题在链路上会被放大,甚至致使整个链路不可用。这意味着流控也须要能够根据响应时间来控制系统的健康,当一个应用响应的时间超过阈值,咱们能够认为这个应用不可控,应该迅速将它降级。
除了流控的激发缘由以外,流控也能够灵活的定义流控的方式。不一样的业务场景,能够采起不一样的流控方式。好比说,对于有的应用,咱们能够简单的丢弃这个请求,有的应用,则须要对下游应用进行降级,甚至直接加入黑名单。而有的应用,则须要把这些多余的请求排队,等到高峰期事后,系统没有那么忙碌以后,再逐步消耗这些流量。
因此,咱们最终的流控框架能够从三个纬度着手,运行情况,调用关系,流控方式。应用能够灵活的根据本身的需求,任意组合。
下面这个是咱们流控的架构图:
第一步,咱们在程序入口给全部的方法都进行埋点;
第二步,咱们把这些埋点方法的运行状态,调用关系统计记录下来;
第三步,咱们经过从预设好的规则中心接收规则,来根据第二步中统计到的系统状态进行控制。
然而,当系统发生流控的时候,系统虽然是安全的,可是它始在一个“受损”状态下运行。因此咱们也在问题排除以后,解除流量控制。用咱们上面的场景做为例子。一个链路上的一个下游应用出现了问题,致使响应时间变长,从而致使上游应用的系统负载太高。过了一下子以后,这个下游应用恢复了,响应时间大大缩短。然而这个时候,上游应用的负载并不能立刻恢复,由于进来的请求已经堆积了一段时间了。
这就意味着,若是咱们采用传统的方式,用系统负载来判断是否应该恢复流控,那么即便问题已经修复,系统地负载仍然处于一个比较高的状态。这样就会致使系统恢复慢。既要迅速恢复,同时也要系统稳定。最后咱们采起的方式是,让 rt,load, 容许经过的 qps 达到动态平衡。
让咱们来看一下最后取得的效果。用了新的算法以后,咱们能够看到系统稳定在必定的范围以内,同时当问题机器恢复以后,流量也可以很快的恢复。
从近几年双 11 零点的业务稳定性上来看,全链路压测是一个明显的分水岭,在全链路压测以后整个站点的稳定性明显好于全链路压测以前。全链路压测已经成为阿里巴巴大促备战的必要环节,不管是双 11 大促、双 12 大促,仍是平时一些比较小的促销活动,每一次活动以前都会进行好几轮的全链路压测来对系统进行一次全方位的模拟验证,提早暴露各个环节的问题。全链路压测的诞生使得阿里大促备战的系统稳定性有了质的提高,被誉为大促备战的核武器。
除了全链路压测来验证咱们的容量规划的正确性之外,流量控制的策略在咱们的大促技术规划时也很重要,限流框架经过 自由组合运行状态,调用链路,限流措施的灵活组合,覆盖了多种业务场景。同时,经过动态平衡,能够作到快恢复,最低的减低对用户使用体验的冲击。流量控制和流量压测二者结合,让咱们的系统稳定健康地渡过各类极限业务场景。