每秒订单数25倍提升,蘑菇街怎样跨过海量服务架构的技术藩篱?

来源:互联网 发布:cell数组赋值 编辑:程序博客网 时间:2024/05/01 20:44
原创 2016-09-27 白辉 


本文根据白辉在2016ArchSummit全球架构师(深圳)峰会上的演讲整理而成。ArchSummit北京站即将在12月2日开幕,更多专题讲师信息请到北京站官网查询(http://bj2016.archsummit.com/)。
本文主要结构如下,读完大概需要12 分钟。
  • 电商系统发展中期面临的一般性问题
  • 系统拆分与服务化过程
  • 购买链路的性能提升
  • 购买链路的稳定性提升
  • 总结及下一步展望
老司机简介
白辉,人称七公,2014年以前在阿里巴巴B2B主要负责Aliexpress资金中心、评价、任务中心等系统。14年8月离开阿里出国游历,15年回国后加入蘑菇街,目前在蘑菇街、美丽说、淘世界大集团共享的电商基础平台负责购物车下单小组及交易平台架构工作
1
电商系统发展中期面临的一般性问题
我总结了一下,一般电商系统发展到中期都会面临三个方面的问题(如图)。
第一方面是业务问题比如,一开始做业务的时候可能很随意,一是并不考虑业务模型、系统架构,二是业务之间的耦合比较严重,比如交易和资金业务,有可能资金和外部第三方支付公司的交互状态耦合在交易系统里,这些非常不利于业务发展。
第二方面是系统问题2014年我们面临单体应用,400人开发一个大应用,扩展性很差,业务比较难做。
第三方面是支撑问题,比如关于环境、开发框架和质量工具等。这些是电商系统发展到中期都会面临的问题,中期的概念是用户过了千万,PV过了1亿。
我们来看一下蘑菇街2015年初面临的问题。蘑菇街2015年用户过亿,PV过10亿,业务在超高速发展,每年保持3倍以上的增长。电商促销、交易、支付等业务形态都在快速膨胀,我们需要快速支持业务发展,而不是成为业务的瓶颈。那么就是要去做系统的拆分和服务化。
2
系统拆分与服务化过程
第二部分的内容,是关于蘑菇街系统拆分与服务化的历程。
按照如下几条思路(见上图),我们进行系统拆分以及服务化。最开始,大家在同一个应用里开发一些业务功能,都是选择速度最快的方式,所有的DB和业务代码都是在一起的。首先我们将DB做垂直拆分。
第二步是做业务系统垂直拆分,包括交易、资金等。
第三步是在系统拆完了之后要考虑提供什么样的API来满足业务的需求?这里我们要做数据建模+业务建模,数据建模方面包括数据表的设计和扩展支持,数据模型应该非常稳定;业务建模方面,使用标准和灵活的API,而且尽量不用修改代码或者改少量代码就能支持业务需求。
第四步是需要将业务逻辑下沉到服务,Web层专注于展示逻辑和编排,不要涉及过多业务的事情。然后用SOA中间件建设服务化系统。最后会做一些服务的治理。
来看一个API服务化的例子,在做服务化之前和做服务化之后,交易创建下单业务有什么不一样。
服务化之前我们面临的问题有:入口分散,如果要在底层做任何一个微小的改动,十几个入口需要几十个人配合修改,这是非常不合理的一种方式;多端维护多套接口,成本非常高;还有稳定性的问题,依赖非常复杂,维护很难。
我刚到蘑菇街的时候,一次大促活动就导致数据库崩溃,暴露了系统架构很大的问题和总量上的瓶颈。按照上面提到几条思路去做服务化,看看有了哪些改善?
首先是API统一,多个端、多个业务都用统一的API提供
其次是依赖有效管理起来,大事务拆分成多个本地小事务
最后降低了链路风险,逻辑更加清晰,稳定性更好

2015年3月我来到蘑菇街之后,先制订了服务化的规范,探讨了到底什么是标准的服务化。在做服务化的过程中,发现大家代码风格完全不一样,所以制定编码规范非常重要。
2015年8月,我们完成了各个模块的改造,包括用户、商品、交易、订单、促销、退款等,然后有了服务化架构1.0的体系。在此基础之上,我们进一步做了提升流量和稳定性等更深度的建设。2015年9月,我们实施了分库分表和链路性能提升优化,2015年10月做了服务治理和服务保障。
接下来,以服务架构和服务体系建设为主线,讲一下去年整个网站架构升级的过程。
在服务化1.0体系完成之后,我们得到了一个简单的体系,包含下单服务、营销服务、店铺服务、商品服务和用户服务,还有简单的RPC框架Tesla。当时,我们并没有做很多性能优化的事情,但是通过业务流程化简和逻辑优化,每秒最大订单数从400提升到1K,基础服务也都搭建了起来。
有了1.0初步的服务化体系之后,更进一步,我们一是要继续深入网站如资金等的服务化,二是要做服务内部的建设,比如容量、性能,这也是接下来要讲的内容。
3
购买链路的性能提升
这个链路(见图)是比较典型的电商链路,有商品页、下单、支付、营销和库存等内容。一开始每个点都有瓶颈,每个瓶颈都是一个篱笆,我们要正视它,然后翻越它。
我们先来看第一个篱笆墙:下单的瓶颈。
2015年“3.21”大促的时候,DB崩溃了,这个瓶颈很难突破。下一个订单要插入很多条数据记录到单DB的DB表。我们已经用了最好的硬件,但是瓶颈依然存在,最主要的问题就是DB单点,需要去掉单点,做成可水平扩展的。
流量上来了,到DB的行写入数是2万/秒,对DB的压力很大。写应该控制在一个合理的量,DB负载维持在较低水平,主从延时也才会在可控范围内。所以DB单点的问题非常凸显,这座大山必须迈过去,我们做了一个分库分表组件TSharding来实施分库分表。
将我们写的分库分表工具与业界方案对比,业界有淘宝TDDL Smart Client的方式,还有Google的Vitess等的Proxy方式,这两种成熟方案研发和运维的成本都太高,短期内我们接受不了,所以借鉴了Mybatis Plugin的方式,但Mybatis Plugin不支持数据源管理,也不支持事务。
我大概花了一周时间写了一个组件——自研分库分表组件TSharding(https://github.com/baihui212/tsharding),然后快速做出方案,把这个组件应用到交易的数据库,在服务层和DAO层,订单容量扩展到千亿量级,并且可以继续水平扩展。TSharding上线一年之后,我们将其开放出来。
第二个篱笆墙就是营销服务RT的问题。促销方式非常多,包括各种红包、满减、打折、优惠券等。实际上促销的接口逻辑非常复杂,在“双11”备战的时候,面对这个复杂的接口,每轮链路压测促销服务都会发现问题,之后优化再压测,又发现新的问题。
我们来一起看看遇到的各种问题以及是如何解决的。首先是压测出现接口严重不可用,这里可以看到DB查询频次高,响应很慢,流量一上来,这个接口就崩溃了。那怎么去排查原因和解决呢?
首先是SQL优化,用工具识别慢SQL,即全链路跟踪系统Lurker。
这张图我简单介绍一下。遇到SQL执行效率问题的时候,就看是不是执行到最高效的索引,扫表行数是不是很大,是不是有filesort。有ORDER BY的时候,如果要排序的数据量不大或者已经有索引可以走到,在数据库的内存排序缓存区一次就可以排序完。
如果一次不能排序完,那就先拿到1000个做排序,然后输出到文件,然后再对下1000个做排序,最后再归并起来,这就是filesort的大致过程,效率比较低。所以尽量要走上索引,一般类的查询降低到2毫秒左右可以返回。
其次是要读取很多优惠规则和很多优惠券,数据量大的时候DB是很难扛的,这时候我们要做缓存和一些预处理。特别是查询DB的效率不是很高的时候,尽量缓存可以缓存的数据、尽量缓存多一些数据。但如果做缓存,DB和缓存数据的一致性是一个问题。
在做数据查询时,首先要看本地缓存有没有开启,如果本地缓存没有打开,就去查分布式缓存,如果分布式缓存中没有就去查DB,然后从DB获取数据过来。需要尽量保持DB、缓存数据的一致性,如果DB有变化,可以异步地做缓存数据失效处理,数据百毫秒内就失效掉,减少不一致的问题。
另外,如果读到本地缓存,这个内存访问比走网络请求性能直接提升了一个量级,但是带来的弊端也很大,因为本地缓存没有办法及时更新,平时也不能打开,因为会带来不一致问题。
但大促高峰期间我们会关闭关键业务数据变更入口,开启本地缓存,把本地缓存设置成一分钟失效,一分钟之内是可以缓存的,也能容忍短暂的数据不一致,所以这也是一个很好的做法。
同样的思路,我们也会把可能会用到的数据提前放到缓存里面,做预处理。在客户端进行数据预处理,要么直接取本地数据,或者在本地直接做计算,这样更高效,避免了远程的RPC。大促期间我们就把活动价格信息预先放到商品表中,这样部分场景可以做本地计价,有效解决了计价接口性能的问题。
再就是读容量问题,虽然缓存可以缓解压力,但是DB还是会有几十K的读压力,单点去扛也是不现实的,所以要把读写分离,如果从库过多也有延时的风险,我们会把数据库的并行复制打开。
我们来看一下数据。这是去年“双11”的情况(如图)。促销服务的RT得到了有效控制,所以去年“双11”平稳度过。
接下来讲一个更基础、更全局的优化,就是异步化。比如说下单的流程,有很多业务是非实时性要求的,比如下单送优惠券,如果在下单的时候同步做,时间非常长,风险也更大,其实业务上是非实时性或者准实时性的要求,可以做异步化处理,这样可以减少下单对机器数量的要求。
另外是流量高峰期的一些热点数据。大家可以想象一下,下单的时候,一万个人竞争同一条库存数据,一万个节点锁在这个请求上,这是多么恐怖的事情。
所以我们会有异步队列去削峰,先直接修改缓存中的库存数目,改完之后能读到最新的结果,但是不会直接竞争DB,这是异步队列削峰很重要的作用。还有,数据库的竞争非常厉害,我们需要把大事务做拆分,尽量让本地事务足够小,同时也要让多个本地事务之间达到一致。
异步是最终达到一致的关键,异步的处理是非常复杂的。可以看一下这个场景(见图),这是一个1-6步的处理过程,如果拆分成步骤1、2、3、4、end,然后到5,可以异步地做;6也一样,并且5和6可以并行执行。同时,这个步骤走下来链路更短,保障也更容易;步骤5和6也可以单独保障。所以异步化在蘑菇街被广泛使用。
异步化之后面临的困难也是很大的,会有分布式和一致性的问题。交易创建过程中,订单、券和库存要把状态做到绝对一致。但下单的时候如果先锁券,锁券成功了再去减库存,如果减库存失败了就是很麻烦的事情,因为优化券服务在另外一个系统里,如果要同步调用做券的回滚,有可能这个回滚也会失败,这个时候处理就会非常复杂。
我们的做法是,调用服务超时或者失败的时候,我们就认为失败了,就会异步发消息通知回滚。优惠券服务和库存服务被通知要做回滚时,会根据自身的状态来判断是否要回滚,如果锁券成功了券就回滚,减库存也成功了库存做回滚;如果库存没有减就不用回滚。
所以我们是通过异步发消息的方式保持多个系统之间的一致性;如果不做异步就非常复杂,有的场景是前面所有的服务都调用成功,第N个服务调用失败。另外的一致性保障策略包括Corgi MQ生产端发送失败会自动重试保证发成功,消费端接收ACK机制保证最终的一致。另外,与分布式事务框架比起来,异步化方案消除了二阶段提交等分布式事务框架的侵入性影响,降低了开发的成本和门槛。  
另一个场景是,服务调用上会有一些异步的处理。以购物车业务为例,购物车列表要调用10个Web服务,每一个服务返回的时间都不一样,比如第1个服务20毫秒返回,第10个服务40毫秒返回,串行执行的效率很低。
而电商类的大多数业务都是IO密集型的,而且数据量大时还要分批查询。所以我们要做服务的异步调用。比如下图中这个场景,步骤3处理完了之后callback马上会处理,步骤4处理完了callback也会马上处理,步骤3和4并不相互依赖,且处理可以同时进行了,提高了业务逻辑执行的并行度。
目前我们是通过JDK7的Future和Callback实现的,在逐步往JDK8的Completable Future迁移。这是异步化在网站整体的应用场景,异步化已经深入到我们网站的各个环节。
刚才我们讲了链路容量的提升、促销RT的优化,又做了异步化的一些处理。那么优化之后怎么验证来优化的效果呢?到底有没有达到预期?我们有几个压测手段,如线下单机压测识别应用单机性能瓶颈,单链路压测验证集群水位及各层核⼼系统容量配比,还有全链路压测等。
这是去年“双11”之前做的压测(见图),达到了5K容量的要求。今年对每个点进一步深入优化,2016年最大订单提升到了10K,比之前提升了25倍。实际上这些优化可以不断深入,不仅可以不断提高单机的性能和单机的QPS,还可以通过对服务整体上的优化达到性能的极致,并且可以引入一些廉价的机器(如云主机)来支撑更大的量。
我们为什么要做这些优化?业务的发展会对业务系统、服务框架提出很多很高的要求。因此,我们对Tesla做了这些改善(见图),服务的配置推送要更快、更可靠地到达客户端,所以有了新的配置中心Metabase,也有了Lurker全链路监控,服务和服务框架的不断发展推动了网站其他基础中间件产品的诞生和发展。2015年的下半年我们进行了一系列中间件的自研和全站落地。
我们得到了服务架构1.5的体系(见图),首先是用户服务在最底层,用户服务1200K的QPS,库存250K,商品服务400K,营销200K,等等。
接下来我们看一下这一阶段,Tesla开始做服务管控,真正成为了一个服务框架。我们最开始做发布的时候,客户端、服务端由于做的只是初级的RPC调用,如果服务端有变更,客户端可能是几秒甚至数十秒才能拉到新配置,导致经常有客户投诉。
有了对服务变更推送更高的要求后,我们就有了Matabase配置中心,服务端如果有发布或者某一刻崩溃了,客户端马上可以感知到,这样就完成了整个服务框架连接优化的改进,真正变成服务管控、服务治理框架的开端。
4
购买链路的稳定性提升    
有了上面讲到的服务化改进和性能提升之后,是不是大促的时候看一看监控就行了?其实不是。大流量来的时候,万一导致整个网站崩溃了,一分钟、两分钟的损失是非常大的,所以还要保证服务是稳的和高可用的。只有系统和服务是稳定的,才能更好地完成业务指标和整体的经营目标。
下面会讲一下服务SLA保证的内容。
首先SLA体现在对容量、性能、程度的约束,包括程度是多少的比例。那么要保证这个SLA约束和目标达成,首先要把关键指标监控起来;第二是依赖治理、逻辑优化;第三是负载均衡、服务分组和限流;第四是降级预案、容灾、压测、在线演练等。
这是我们服务的关键指标的监控图(见上图)。支付回调服务要满足8K QPS,99%的RT在30ms内,但是图中监控说明SLA未达到,RT程度指标方面要优化。
服务的SLA保证上,服务端超时和限流非常重要。如果没有超时,很容易引起雪崩。
我们来讲一个案例,有次商品服务响应变慢,就导致上层的其他服务都慢,而且商品服务积压了很多请求在线程池中,很多请求响应过慢导致客户端等待超时,客户端早就放弃调用结果结束掉了,但是在商品服务线程池线程做处理时拿到这个请求还会处理,客户都跑了,再去处理,客户也拿不到这个结果,最后还会造成上层服务请求的堵塞,堵塞原因缓解时产生洪流。
限流是服务稳定的最后一道保障。一个是HTTP服务的限流,一个是RPC服务的限流。我们服务的处理线程是Tesla框架分配的,所以服务限流可以做到非常精确,可以控制在服务级别和服务方法级别,也可以针对来源做限流。
我们做了这样一系列改造之后,服务框架变成了有完善的监控、有负载均衡、有服务分组和限流等完整管控能力的服务治理框架。服务分组之后,如果通用的服务崩溃了,购买链路的服务可以不受影响,这就做到了隔离。
这样的一整套服务体系(如图)就构成了我们的服务架构2.0,最终网站的可用性做到了99.979%,这是今年6月份的统计数据。我们还会逐步把服务的稳定性和服务质量做到更好。
5
总结及下一步展望
最后总结一下,服务框架的体系完善是一个漫长的发展过程,不需要一开始就很强、什么都有的服务框架,最早可能就是一个RPC框架。服务治理慢慢随着业务量增长也会发展起来,服务治理是服务框架的重要组成部分。
另外,Tesla是为蘑菇街业务体系量身打造的服务框架。可以说服务框架是互联网网站架构的核心和持续发展的动力。选择开源还是自建,要看团队能力、看时机。我们要深度定制服务框架,所以选择了自研,以后可能会开源出来。
服务框架是随着业务发展不断演变的,我们有1.0、1.5和2.0架构的迭代。要前瞻性地谋划和实施,要考虑未来三年、五年的容量。有一些系统瓶颈可能是要提前解决的,每一个场景不一样,根据特定的场景选择最合适的方案。
容量和性能关键字是一切可扩展、Cache、IO、异步化。目前我们正在做的是服务治理和SLA保障系统化,未来会做同城异地的双活。
谢谢大家!
今日荐号:聊聊架构
聊聊架构是InfoQ旗下的垂直社区,主要关注传统企业以及互联网企业的系统架构,研究并探讨架构实践中的难点和痛点。定期组织线上群分享活动。
延展阅读(点击标题):
  • 一篇文了解DevOps:从概念、关键问题、兴起到实现需求
  • 架构师多如过江之鲫,但你真的了解架构师这个工种吗?
  • 左耳朵耗子:什么是工程师文化?

QCon上海免费场报名:微服务实践与架构演进之路专题将会邀请具有实战经验的一线技术专家,为大家带来对微服务架构落地具有指导意义的分享,了解在实践微服务化过程中遇到的诸多坑,以及解决这些问题的模式或经验总结,希望能给大家带来一些新的思考。戳阅读原文免费报名!


今晚八点半,熊猫TV直播大咖说辩论赛:
「微信小程序来了,究竟谁程序员还是产品运营的春天?」
扫描二维码,回复「InfoQ」报名!

阅读原文

“从每秒400单交易量到每秒1万单,25倍的增长背后,是怎样的优化与实践?这其中的障碍,蘑菇街技术团队如何跨越应对?每秒能支撑的峰值订单数是衡量电商系统高并发可扩展能力的重要体现,在电商内提升每秒支撑订单数存在无数的方法,每一个方法都存在各自的优化角度和对应的障碍挑战,如何在一开始根据自身企业的特点选择最合适的优化路径,并其后在这路径上高效贯彻和执行,对于团队尤其是初创团队而言都不是简单的事情。
  受访嘉宾简介七公,原名白辉,2014年以前在阿里巴巴B2B主要负责Aliexpress资金中心、评价、任务中心等系统。14年8月离开阿里出国游历,15年回国后加入蘑菇街,目前在蘑菇街、美丽说、淘世界大集团共享的电商基础平台负责购物车下单小组及交易平台架构工作。
  七公不仅在日前结束的 ArchSummit 深圳 2016 全球架构师峰会上做了精彩分享,他也在 InfoQ大咖说上做了一期视频分享直播。感兴趣的同学请戳标题观看:
  从阿里到蘑菇街,我是如何探索电商平台服务架构的丨InfoQ大咖说
  InfoQ:在2014年以前您在阿里巴巴B2B负责Aliexpress资金中心等项目,能否谈谈在阿里的这段经历给您之后出国游历、回国加入蘑菇街带来了哪些动因和影响?
  七公:我是2011年3月加入阿里巴巴的,彼时阿里整个的业务、技术体系都处在一个飞速发展的时期,我个人也获得了飞快的成长。受去看世界的梦想推动,2014年8月我和女朋友一起从阿里辞职,出国游历了半年。
  回来之后,阿里当时内部各方面整体已经趋向稳定,我希望找到另一家飞速发展的公司,北京上海找了一圈不满意,最终还是回到了杭州,加入了蘑菇街。在蘑菇街一年的时间里,我们业务和技术都获得了火箭般的飞跃式前进,我一年里的进步和收获比在其他公司呆两年得到的还要多,实现了和公司的共进步、同成长。
  InfoQ:您加入蘑菇街电商团队后带领团队同学仅用一年便完成服务架构的各阶段升级,能否谈谈你们是如何规划优化路径并高效实现的?在高效率工作上你们有什么经验或技巧可以分享?
  七公:第一个阶段【蘑菇街系统拆分&服务化1.0体系构建】,是我们做PHP全面转型Java体系、初步建成电商基础服务中心的战略规划,在面临不停歇的业务需求和巨大的系统改造压力下,我们采用瀑布流工程方法,通过规划、分析、设计实现、测试、服务产品&文档交付的过程,高质量地把第一阶段的服务化建设根基像打桩一样打牢,然后通过进一步的迭代开发不断完善。
  第二阶段【购买链路核心服务的性能提升&服务架构1.5】和第三阶段【服务SLA保障推动稳定性提升&服务架构2.0】,实际上是业务迅猛发展、流量不断上涨、日常和大促稳定性保障的强烈需求推动我们自身服务架构的升级。我们通过引入Scrum的敏捷开发模式,项目中的每个人都是猪(敏捷开发中,猪为项目负责人,鸡只是普通参与者,寓意来自猪要牺牲才能提供食物而鸡只要下个蛋就行了),每个人都要为服务框架升级和项目进展负责。
  我们先后有十人以上共同推进了服务框架负载均衡、降级限流、连接切换优化等基础框架演进,以及监控、服务端超时控制、多版本、分组隔离、动态路由等服务治理体系完善。
  总结一下: 高效推进上,我们的经验是首先要采用项目的方式进行管理,再一个是时机不同、阶段不同,选择的项目工程方法也不一样
  新架构探索:建议采用传统的瀑布式和迭代式开发;
  架构的持续迭代:可以尝试一些新的开发方法。
  InfoQ:能否介绍蘑菇街系统架构的中间件系统?蘑菇街的一系列中间件是如何实现Web应用层和基础设施层对接的,各中间件如何确保在全站稳定落地?
  七公:蘑菇街购买链路服务架构示意图:
  
  从蘑菇街购买链路服务架构1.0到1.5,我们完成了服务化框架Tesla、分库分表TSharding、分布式缓存MoguCache、Corgi MQ、配置中心Metabase、调用链跟踪Lurker等一系列重要中间件的自研、完善和在全站落地。这一系列中间件的研发,是随着业务系统和服务框架的不断发展(最早我们只有Tesla一个中间件)而逐步衍生出来的。
  2015年初,蘑菇街全网还在PHP体系,Tesla框架诞生后,我们先构建了用户、商品、交易、促销等一系列的电商基础服务中心:
  Tesla框架支撑了PHP Web应用到服务中心的PRC调用场景;
  服务中心内部有数据容量提升需求,所以先后有了TSharding和Raptor分库分表中间件;
  服务内部有异步化处理需求,有了Corgi MQ;
  服务中心内部有分布式缓存需求,所以有了MoguCache等;
  所以 服务框架是支撑和推动整个网站架构发展的核心和源动力。2015年底我们启动了PHP Web单体应用拆分为一个个Java Web业务应用和前后端分离项目,很快购买链路完成了PHP体系到Java生态的彻底升级。
  Tesla走向真正的服务框架(而不仅仅是一个RPC框架)是随着业务的不断发展和业务系统的强烈要求开始的。最早业务系统面临服务发布时不平滑(客户端几秒甚至数10秒后才拉到更新的IP列表)等问题,以及业务服务蓬勃发展时期强烈的服务治理需求,Tesla不断进行服务框架的改造升级:
  通过新的配置中心Metabase的诞生和客户端拉取配置优化、客户端响应服务端连接关闭事件解决连接优化问题;
  通过对监控预警、动态限流、服务端超时、服务分组等的支持完善了服务治理体系。
  实际上业界的众多服务框架也是这么一步步发展起来的,没有捷径
  中间件在全站的有效落地,是靠中间件团队和业务系统支撑团队密切配合完成的。新的中间件刚刚开发出来,肯定会有各种问题出现,但是中间件也是业务系统的实际需求推动才产生的,所以双方的目标、利益点是相同的。我们会采用项目的方式,每个项目成员都对中间件的使用推广和自身完善负责,共同推动中间件在全站的稳定落地。
  InfoQ:在中间件研发过程中,开源技术起到怎样的作用?
  七公:蘑菇街是拥抱开源技术的。在我们的技术体系中,很大一部分基础技术组件依赖于开源产品。我们的Tesla服务框架是基于Netty开发的,最早我们用的MQ是RabbitMQ,后来我们才转向自研;我们的Sentry监控平台是基于Grafana;目前我们仍然在广泛使用Kafka来收集全站日志,使用Zookeeper协调分布式系统,使用Hadoop生态来支撑数据平台计算任务等等。
  而自研Tesla、Corgi MQ等等中间件的原因是因为这些是支撑我们网站发展的核心产品,我们必须要能够完全掌控、有能力做到深度定制,以便快速支持业务发展,而不是成为业务发展的瓶颈和阻碍;而这些中间件的诞生、持续发展和在全站落地之后,变成了我们技术团队乃至整个蘑菇街的核心竞争力之一。
  针对纯技术的中间件/产品,我们会选择性的开源。TSharding是我们最早的分库分表中间件,之前因为有小米、有赞等不少技术同仁都有咨询,所以我们开放在了Github上,见:
  https://github.com/baihui212/tsharding。
  InfoQ:如何通过数据分析来指导“前瞻性地谋划实施、支撑业务快速发展”?在电商中哪些数据发生怎样的变化会给系统架构带来预警,提示需要改良或优化?能否结合谈谈你们的峰值系统的监控架构和方案?
  七公:“前瞻性地谋划实施”可以通过关注业务数据和系统数据的增长变化情况来获得一个合理的度。通过当前业务的增速能推算出来三五年内的业务爆发和数据增长情况,如果有些架构上的不适宜(如过度中心化或存在易攻击点、系统难以扩展或者稳定性难以保障等问题),要尽早规划新的架构形态并快速推进实施,提早解除可能阻碍业务发展的绊脚石。但是也不能过度设计,考虑五年以后、十年以后的情况做设计,可能还未到时候,现有架构早就过时了。
  电商数据比较复杂,概括如下:
  业务数据
  目前我会关注DAU,分平台的GMV、UV、客单价、支付订单数、支付用户数等。
  系统数据
  主要是容量和系统运行情况,容量包括数据库表空间、磁盘使用情况、服务应用的水位、缓存集群的分片情况等;系统运行状态主要包括QPS、RT、调用成功率、CPU占用率、内存使用、IO等。
  只要持续关注这些核心数据,才能敏锐地把控到系统接下来的发展趋势和改造方向。
  蘑菇街大促峰值的监控分两部分:一部分是实时业务监控,播报实时PV、UV、购买订单数、GMV、客单价的情况,这部分是通过实时计算平台的流式计算任务来完成的,延迟在秒级左右;另一部分是实时系统监控,我们是通过异步上报、LogAgent收集、实时统计分析来保证10s左右的延迟就能把系统的实时统计指标呈现在可视化监控平台上。前者给业务方密切关注,后者则是我们做大促保障指挥决策、预案执行的哨兵和自动化告警的主要手段。
  InfoQ:目前蘑菇街的架构是否已经达到了“该优化的已经优化了”的阶段?您将在ArchSummit的分享中提到“25倍”的优化路径,在您的猜想下,25倍是否是优化的极限,您认为短期未来还可以达到多少,如何做到?
  七公:蘑菇街业务每年都保持3倍多的迅猛增长,对技术的挑战一直非常大。2015年我们主要完成了业务应用服务化建设&服务架构升级、基础中间件研发落地、前后端分离、稳定性平台建设&大促保障常态化等重大技术改造,为网站架构的进一步发展打下了很好的基础。
  目前我们还面临诸多问题和挑战,比如前端组件化的建设和新业务的快速交付、蘑菇街/美丽说/淘世界整个集团各平台业务发展的快速支撑和系统化的稳定性保障&质量保障能力;JDK8、异步框架等技术在全站的落地;应用高性能的持续优化、虚拟化&私有云的持续建设等等,蘑菇街还远未到“该优化的已经优化了”的阶段。我们要做的就是把每行代码都写好、每件事情都做到位,让我们的系统变的越来越强大,同时用更少的人力和机器成本去支持更大体量的业务。
  关于优化的极限问题,最终追求的极限不是倍数,是在机器数上。机器堆的多了,自然可以支撑更大的流量,但是我们目前在做的是用更少的机器,支持更多倍的流量。目前我们主要还是进一步提高虚级化占比的方式(已逼近上限)和单机能力提升(还大有可为)的方式来进行的。
  InfoQ:为什么您认为“根据场景来选用性能优化方案,没有通用方案”,蘑菇街以前是否考虑过“通用方案”的设计?能否结合蘑菇街架构升级案例谈谈这个体会?
  七公:性能优化有很多种手段:
  硬件
  对硬件更新换代、提升硬件能力、调优硬件参数可以提升性能,横向扩展方面加机器也可以提升性能。
  软件
  对数据库/Web Server等软件进行配置优化、对CPU执行效率做优化、对IO效率做优化、对程序CPU计算复杂度做优化等等都可以提升性能,甚至仅仅做业务化简也能得到很可观的RT的降低。
  2015年初蘑菇街面临非常大的性能问题,只能支撑400单左右每秒的交易创建,严重不满足业务超高速发展和大促迅猛流量的要求。我们在完成系统拆分&服务化1.0体系构建后,开始了购买链路的专项性能提升项目。这个项目过程中翻越了许多障碍、篱笆,比如DB单点写瓶颈是一直压在头上的一座大山。
  我们通过自研分库分表组件TSharding,完成分库分表,最终下单服务支持了写入的无限水平扩展,订单库容量提升到了千亿级规模;营销服务的RT不稳定,每轮压测,营销服务都能再进一步,然后遇到下一个问题;我们通过SQL优化、缓存&预处理、读写分离等手段,大促期间最终计价接口RT稳定在7ms;异步处理非常有必要性,能大大降低服务响应RT,然后我们通过自己的方式解决异步化后的分布式事务问题,等等。
  我们优化的案例还有很多,优化的过程很类似:找到瓶颈点——优化——压测验证然后再循环。但是最优的方案往往都是针对该场景和问题定制的,不应该去追求通用方案,也不会有通用方案。
  InfoQ:并没有很多技术人员能有处理海量服务的机会,在从事这方面的工作中您有什么特别的感悟或经验可以和大家分享吗?
  七公:我的体会是:只有自己经历过、尝试过的,才能真正成为自己的。如果有意愿深入接触高并发高可用高可扩展服务架构,但是目前还没有机会的,建议尽早换到业务在快速发展的有大流量场景的互联网公司,给自己挑战自我的机会。
微信扫一扫
关注该公众号
0 0
原创粉丝点击