BT

你的观点很重要! 快来参与InfoQ调研吧!

有赞11·11:全链路压测方案设计与实施详解

| 作者 金瑞敏 关注 0 他的粉丝 发布于 2017年11月11日. 估计阅读时间: 15 分钟 | ArchSummit社交架构图谱:Facebook、Snapchat、Tumblr等背后的核心技术

A note to our readers: As per your request we have developed a set of features that allow you to reduce the noise, while not losing sight of anything that is important. Get email and web notifications by choosing the topics you are interested in.

2017年双十一即将来临,对于买家来说是一年一度的购物狂欢,可是对于电商公司的技术人员来说,却是一年一次的大考。如何用更少的预算完成指定当前业务规模的流量高峰,是技术的永恒主题。

由InfoQ举办的ArchSummit全球架构师峰会即将于12月8-11日北京举行,大会与阿里巴巴合作策划了双11架构专场,并邀请了顶级技术专家担任出品人,设置了“新一代DevOps”、“人工智能与业务应用”、“架构升级与优化”等17个热门话题,目前大会日程已出,欢迎前来讨论交流。

有赞在双十一之前完成了全链路压测方案,并把它用于大促的扩容和容量验证,取得了不错的成果。

在电商公司待过的技术同学都知道,在大促来临时,整个集群的最高峰压力将是正常时间的几十倍,最高峰持续的时间会特别短,然后回落到正常水平的几倍。所以,我们可能会自然而然地想到,把整个集群扩容几十倍的机器,在双十一当天应对几十倍的流量,然后第二天减至正常量,就可以完成大促的考验。事实情况是否真的这么简单?

大促保障的困难

用户购买商品的链路是一条很长很复杂的系统集群,中间会涉及到店铺、商品、会员、营销、交易、支付等6大核心模块,每个模块又会涉及到多个不同的服务化系统单元,我们把这一条骨干的链路就叫做核心链路。

大家都知道,双十一当天,真正爆增的其实是买家的购买量,像开店/商品上架等功能,其实并发量没什么变化。也就是说,真正的压力其实是在核心链路上面,如果把所有的系统都扩容几十倍,本身就是一个很大的浪费。正常来说,一个稍有规模的电商公司,日常有几千台机器维持正常的运转,本身就是一个较大的开销,如果突增几十倍的系统开销,对于公司的财务也是很大的压力。所以,一个较理想的方法,是只把核心链路的系统扩大几十倍的系统吞吐量,就可以达到目标。

困难一

大型的分布式系统其实错综复杂,公司需要维持成百上千的服务化系统。理论上来说, 只有少部分系统是核心链路的系统。但是在实际情况下,因为公司人员的关系,可能会把某些非核心系统,不知不觉加入到了核心链路中。所以,第一件要做的事情,就是把非核心系统从核心链路上剔除。

困难二

一般公司都会在线下搭建性能测试环境,在该环境下,我们的测试同学可 以借助一些测试工具,去压单机单接口的性能。假如,店铺的首页面,我们在性能测试环境下,得出单机单接口的QPS峰值是500,这是否意味着, 要达到10w的QPS,我只需要设置200台机器就可以了呢?答案当然是否定的。因为任何的页面接口都不是单独存在的,都会受到公共资源的制约,如:DB、Redis、MQ、网络带宽等。比如当店铺首页达到10w QPS的时候,商品详情页可能要达到8w的QPS了,也会消耗公共资源。当公共资源的能力下降时,势必会影响所有的系统。所以,通过单机性能算出来的理论值,跟实际情况会相差很远。

困难三

正常来说,任何大促都会有业务目标,这个目标一般是拿GMV进行评估。但是我们在进行系统容量评估的时候,一般会想扩大多少台机器。那么GMV跟核心链路各个系统之间的机器数量的转化关系是什么样的?

困难四

做过大型分布式系统的同学,可能都知道一个事实,即整个集群的性能其实取决于接口的短板效应。而这个短板的接口,在正常的流量下,是不会显现出来的。只有集群的整体压力达到一定值的情况下,才会偶尔显现, 然后造成雪崩效应,拖累整个系统集群。所以,如何在大促之前找到这些短板,然后把它们一个一个优化,这件事情就显得非常重要。

困难五

应用系统的扩容相对而言是比较简单的,完成大促之后,可以很容易归还。但是DB等核心资源的扩容其实并不容易,而且资源不可能归还(数据不不可丢失)。

事实是检验真理理的唯⼀一标准,上面提到的五个困难,其实都可以用线上真实压测的办法去检验。业内大型电商公司,会用全链路压测的方案去指导扩容的进程,有赞也不例外。今年双十一,有赞用该方案完成了对核心链路20倍的扩容,但是整个集群的规模只是扩大了了一倍多一点。

有赞全链路压测的设计方案

全链路压测的目标是让双十一要发生的事情提前发生,并验证在该情况下系统表现良好。做线上压测,有一个很重要的原则:线上系统是不允许有脏数据的。

有赞的压测设计方案,可以用几句简单的话做概括:

  • 压测流量落影子库,正常流量落正常库。
  • 压测不能把系统压崩溃。
  • 压测是模拟双十一流量最高峰时用户的购物行为,所以综合性的流量模型需要跟实际情况相符。

全链路压测的总体设计

有图有真相,我们先上图。

在上述图中,我们明显可以看到,全链路压测有几个关键部分:

  1. 数据工厂,负责造请求数据。
  2. 大流量下发器,产生很大的压力去压系统。
  3. 线上服务集群同时处理压测请求+正常请求。
  4. 压测流量落影子存储,正常流量落正常存储。
  5. 压测流量对于外部的依赖走mock服务器,正常流量走正常外部集群。
  6. 水位检测,需要检测存储+线上应用服务器的健康度,并且能够干预流量下发。

关键模块的设计方案

数据工厂设计

数据工厂是压测的一个核心部件,主要由Hive表的集合+各种导入、导出脚本组成。

数据工厂的目的是保存压测需要准备的所有数据,数据需要做清洗,比如:

  • 商品未下架
  • 商品的库存无限
  • 营销活动的信息有效,未过期
  • 店铺未关闭等等

场景的定义:场景的定义关系到数据的准备,正常来说,压测只会压随着买家人数暴增、系统的压力立即增加的场景,我们把这个场景涉及到的系统叫做“核心链路”。

影子存储的设计与路由能力

  1. DB、路由方式由RDS提供,存储可以有两种方式:
    • 影子表与正常表存在同样的instance、不同的schema中。这个方案不需要增加额外的存储开销,相对更便宜,但是风险较高(把库压死了会影响线上业务)。
    • 影子表与正常表存在不同的instance、相同的schema中。这个方案相对较贵,需要额外搭建DB集群,但是安全性较高。

    我们选择的是第一个方案。

  2. Redis:通过key值来区分。压测流量的key值加统一前缀,通过Redis-Client做路由。
  3. HBase:通过命名空间做隔离。影子空间加前缀,提供统一的HBase Client做数据访问,由该Client做路由。
  4. ES:通过index名字来区分。影子的索引统一加前缀,提供统一的ES Client做数据访问,由该Client做路由。

线上应用集群的变更

  1. 统一线上应用对于数据的访问(DB+ES+HBase+Redis),提供统一的Client。
  2. 由于线上的应用都是服务化工程,远程调用时,必须具备压测流量的标记透传能力。
  3. 线上的少部分应用,需要访问第三方服务,比如:物流、支付。这些应用需要改造为压测的流量直接访问mock服务器。

全布式流量下发器设计与链路设计的能力

我们选用gatling作为我们的流量下发器实现。

数据文件的内容

每一种场景都有不同的数据文件,数据文件由场景相对应的多种url组合而成。比如:我们本次压测会压“无优惠的场景、秒杀场景、满减场景、拼团场景” 等等。无优惠的场景分为“店铺首页、商品详情页、加购物车页、下单页、支付页、支付成功页”等等。这个文件不涉及漏斗转化率。一般来说,一个数据文件很大(至少是G级别的)。所以我们的数据文件内容格式为:

  • 所有的数据⽂文件
    • 无优惠的场景数据文件
      • 场景集合1
        • 店铺首页URL
        • 商品详情页URL
        • 加购物车页URL
        • 下单页URL
        • 支付页URL
        • 支付成功页URL
      • 场景集合2
        • 店铺首页URL
        • 商品详情页URL
        • 加购物车页URL
        • 下单页URL
        • 支付页URL
        • 支付成功页URL
    • 秒杀场景数据文件
    • 满减场景数据文件
    • 拼团场景

流量下发脚本的内容

流量下发脚本的核心是控制漏斗转化率:

  1. 不同场景的流量配比。
  2. 每个场景下面,url从上往下的漏斗转化率。

gatling提供天然的转化率配置脚本,用起来非常方便。有兴趣的同学可以自行Google。

水位检测系统的能力设计

这个是一个很重要的模块,在项目启动之初,我们希望以实时计算的方式,一边采集各个应用系统的资源使用情况+接口耗时+业务正确率,一边向gatling发送流量干预信号,以做到自动保护系统的目的。由于时间关系,我们并未实现这一方案。取而代之的是人肉查看实时监控界面的方式,人为去干预gatling的流量下发情况。

全链路路压测的实施

如果实施过全链路压测的项目,大家都会有一个共同的感受:做基础的组件容易,让核心业务去完成相关的升级与验证工作很难。原因只有一个:需要用全链路压测的公司,业务规模都很大,涉及的团队会特别多。梳理理清楚庞大的业务,让所有的业务团队一起发力,本身就是一件很难的事情。

我们把链路压测的实施分为以下几个阶段:

  1. 基础中间件开发,各种框架升级开发,压测器研究与脚本开发。
  2. 业务升级与线下验证(人工点击,数据落影子库)
  3. 业务升级与线上验证(人工点击,数据落影子库)
  4. 数据工厂数据准备。
  5. 小流量下发验证(用gatling下发,数据落影子库)
  6. 大流量量压测与系统扩容

第2、3、5阶段,需要借助业务测试同学的力量;第4阶段,需要借助业务开发同学的力量;第6阶段,则需要借助业务团队+运维同学的力量。

由于每个阶段人员都不太一样,所以需要每一个阶段都组织不同成员的虚 拟小组,借助各个团队的力量完成相应的工作。

压测过程中的重要细节与把控

流量爬升的规律

正常来说,在大促之前做压测,目的一般是给扩容/优化做方向性的指导。

假设我们双十一需要扩大20倍的容量以应对高峰,那我一定不会一开始 就拿20倍的流量去压我们的系统,因为这样做的话,所有的系统都会在一瞬间就挂掉,这样没有任何意义。我们的做法是,阶段性的爬坡打流量,然后把系统的能力一段一段提升上去。

例如:

  1. 第一天,我们会以日常流量的最高峰为起始流量,然后爬坡到一个流量高峰A,记为第一天的目标。在压测之前先做一次扩容。在压测中,碰到了某个瓶颈了,通过增加该系统的机器来提升能力。
  2. 第二天,我们以A为起始流量,然后再次爬坡到B。同样压测前做扩容+压测中碰到瓶颈加机器。
  3. 以此类推,一直到最终流量达到目标流量为止。
  4. 每一天的压测,也需要以慢慢爬坡的方式提升流量。在爬坡的某个高度稳定5分钟,然后再次爬坡。稳定时间5分钟,爬坡时间30秒。

非核心链路进核心链路的问题

发现并解决这个问题,本身就是压测的目的之一。

正常来说,非核心链路,在大促来临时不会扩大多少容量。当压测的压力增大时,很容易通过系统报警查到。

当发现这个问题的时候,一定要坚决要求业务方做系统改造,把非核心系 统的强依赖去掉。解耦的技术有很多,需要根据不同的业务规则来选择方案。比如:业务降级、通过中间件解耦、异步化等。

上下游扩容/代码优化的选择

一般来说,在压测的过程中,当碰到压测流量不能再升高的时候,会有很多原因,我们碰到的情况有以下几种:

  1. 下游的某些服务化工程的能力达到瓶颈了,导致网关RT值升高,拖累整个集群的QPS上不去。
  2. 网关应用自身的能力达到瓶颈。
  3. 中间件/DB能力达到瓶颈。
  4. job的能力达到瓶颈,导致数据处理不够及时。
  5. 流量集中的页面,消耗了集群大量资源,如:店铺首页、商品详情页等。

针对2、3、4这样的情况,我们的选择是毫不犹豫地加机器,代码优化的性价比较低。

针对第1种情况,需要做一些分析,如果这样的能力是在系统设计者的预期之内的,可以选择加机器,如果完全超乎意料的,一定需要通过程序优化来提升能力,否则加了资源,可能还是瓶颈。

针对第5种情况,一定要做的事情是静态化。因为这些流量集中页面,一般都是展示性质的。不管如何做应用内的优化,获得的能力提升远不如做静态化的收益大。

未来展望

全链路压测的方案有赞只是初试牛刀,我们已经看到了这个方案在提升+验证集群处理能力方面巨大的价值。当前,这个方案做得还较粗糙,存在一些问题:

  1. 压测只能在夜间做。
  2. 压测中需要有很多业务开发人员陪同。
  3. 链路规划复杂度太高。
  4. 压测控制台的稳定性还不够高。
  5. 水位检测与流量干预是通过肉眼观察监控来实现。

后续我们团队会继续投入大量精力去完善整个方案。希望可以将压测方案变成:

  1. 线上测试链路的机器人,实时检测线上系统的正确性,同时没有脏数据干扰。
  2. 测试同学手里的工具,做到流量压测常规化,开发同学不用陪同。
  3. 压测可以在白天进行,晚上熬夜毕竟不利于健康。
  4. 链路规划图形化,并与数据工厂结合,完成数据的准备工作。
  5. 通过水位检测与流量干预来保护系统,让业务系统不会被压崩溃。

作者介绍

金瑞敏,有赞核心交易、java框架团队负责人。带领团队完成核心交易平台化体系建设,优化有赞服务化治理方案、环境隔离方案、全链路压测方案等等。长期从事分布式系统的建设与研究。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

大赞 by 文 无忌

大赞

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

1 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT