阿里电商架构演变之路

前言:从网上找的首届阿里中间件技术峰会上的一个报告,2017年7月的,报告的名字叫阿里电商架构演变之路,感觉不错所以看了一遍,在此记录一下,复制了其中大部分内容,并进行了整理,然后在晦涩之处用自己的语言解释了一下,用于个人复习。

参考:

https://yq.aliyun.com/articles/147755

https://developer.aliyun.com/article/161190

目录

第一章 淘宝1.0

第二章 淘宝2.0

2.1 1.0架构出现的问题

2.2 2.0架构

第三章 淘宝3.0

3.1 2.0架构遇到的问题

3.2 2.0到3.0过程中的架构 

3.3 2.0到3.0过程中的架构遇到的问题

3.4 3.0架构

3.4.1 RPC框架

3.4.2 数据库拆分

3.4.3 MQ集群

3.4.4 分布式追踪

3.4.5 其它系统

第四章 淘宝4.0

4.1 3.0架构遇到的问题

4.2 4.0结构

第五章 新起点


第一章 淘宝1.0

整个淘宝网从开始想去创建,到真正上线,总共经历了一个多月的时间。那这一个多月的时间都做了些什么呢?

第一件事情,我们开始做技术选型,决定我们后续怎么发展;第二件事情,如何在一个多月的时间,让我们的网站上线。

我们购买了一套基于LAMP架构的电商网站,并且拿到源代码,我们对其进行二次开发,比如界面的UI改动,上下title的改动,其中最大的改动就是我们对它的数据库做了读写分离。

阿里电商架构演变之路_第1张图片

第二章 淘宝2.0

2.1 1.0架构出现的问题

随着业务量的增长,就会发现一些瓶颈,主要来自于数据库。当时的数据库是MySQL4,还不够稳定,数据库经常会出现死机。

因此,我们直接把数据库换成oracle,通过PHP和oracle直接去连接进行操作,但PHP不支持连接池,即使使用一些开源的PHP中间件,让PHP去连接oracle,还是非常不稳定,连接池的中间件经常卡死。

2.2 2.0架构

我们开始考虑将技术体系转成Java,因为Java在企业级的应用中,有着比较成熟的生态。转化的过程中也还是很坎坷的:第一,我们是一个线上正在运行的系统;第二,系统当时正在大规模的增长。所以说把系统替换成Java,最好的方法就是分块替换。同时发现,oracle的写入量还是比较大的,当时还做了一个search,把产品搜索和店铺搜索放到search里面,这样每一次的请求都打到数据库里面了,这样我们就完成了1.0架构到2.0架构的演进。

阿里电商架构演变之路_第2张图片

第三章 淘宝3.0

3.1 2.0架构遇到的问题

3.2 2.0到3.0过程中的架构 

 所以我们开始对架构升级。第一,我们增加了内存cache,cache主要是解决数据库压力过大的问题,我们自己研制了一套Key/Value 分布式缓存(TAIR),就是在数据库前端加了一个内存cache,缓解了我们数据库的压力。第二,我们增加了分布式文件系统(TFS),之前的文件系统在商用的时候,成本太高,服务器的量非常大,所以我们研发了自己的一套文件系统。

阿里电商架构演变之路_第3张图片

3.3 2.0到3.0过程中的架构遇到的问题

  • 技术团队规模500人左右,维护变得越来越复杂
  • 单一War应用,应用包一直增长,更新业务特性越来越慢;数据逐步形成多个孤岛,无法拉通
  • 基于传统应用开发架构,业务爆发,弹性不足,单点故障影响巨大
  • 还有性能问题。随着前端业务量的增大,服务器逐渐增多的时候,oracle也出现了连接数的瓶颈。所以我们必须开始做新的架构,让整个架构往前走一步。

3.4 3.0架构

我们迈向了3.0架构。系统进行拆分变小,拆分系统主要是把系统分层。把系统分成三类:

第一类是c类,是中心类,比如说会员、商品、店铺等等,基于这些中心上面开发各自的系统。比如说商品详情、交易下单;

还有一些公共的类,是p类,比如交易平台,这是从业务上进行拆分。几个比较知名的项目,比如千岛湖项目(拆分出交易中心、类目属性中心)、五彩石项目(拆分出店铺中心、商品中心、评价中心)。

还有一类是垂直团队类。

伴随着技术架构的改动,我们的业务结构也开始进行改动,开始成立了相应的团队。上图的下半部分就介绍了我们架构的演变过程。开始时,是all in one,1~10在维护一个项目。第二个阶段是10~1000人维护的MVC架构,实现了前后端分离,各司其职。第三个阶段是RPC,就是把各个系统进行拆分,然后各个系统之间进行通信。第四个阶段就是SOA这样一个模式。

这里关于上面所说的分类自己又思考了一下感觉上面描述的并不是很清楚,感觉应该是下面的意思,不保证对哈

C类就是专注于提供一个服务,如会员服务、商品服务、店铺服务。

P类是提供公共服务的一些类,如支付类,不同的业务(淘宝、飞猪)都需要通过此类向银行扣钱。

垂直团队类提供一些合成服务,如有一个读取商品信息接口,此接口需要调用C类中的商品服务、店铺服务,垂直团队实现此接口。

 

阿里电商架构演变之路_第4张图片

3.4.1 RPC框架

我们开发了轻量级的HSF框架,它是基于Java interface 的RPC框架,使得开发系统时就像开发本地应用一样去正常的调用Java。使用这个框架可以真正远程的调用到其他的系统上面。

一般RPC都带着服务发现,服务发现怎么办呢?

一个应用A如何知道应用B里面有多少台机器呢,你的ip又是什么?最简单的方式就是静态列表,记录下ip,做轮询策略,先调用A的1号机,再调用2号机。这样就没法实现一个动态的发现。所以在这个过程中,我们有一个动态的配置中心(configserver),在你服务上线的时候,作为provider把服务放到configserver上去,当需要消费这个服务的时候,会看哪些服务可以调用,然后把这个列表拿到。Configserver会自动把相应的provider的ip推送到consumer上面。然后consumer会自动发现provider的服务,然后彼此会发生一个相互调用关系。如果configserver挂掉之后,你的provider是挂不上去的,但是已经发上去的服务是不受影响的,因为configserver已经把相应的服务推送到consumer上面。当我们把分布式系统变得庞大之后,其实各个系统各司己职就好了。

 

3.4.2 数据库拆分

Oracle其实也产生了性能瓶颈,而MySQL经过了多年发展,已经非常的成熟和稳定了。我们考虑把数据库做拆分,也就是去IOE。对MySQL进行拆分,其实就是按照一定的规则去分库分表。拆分首先就是读写分离,然后做垂直拆分,还有水平拆分。垂直拆分主要是按业务来拆分,当垂直拆分到一定程度之后,有一些大业务还是不能承担这样的数据量,我们只能水平做分库分表,做sharding的拆分。分库分表就基于某一些主键算,如果主键符合什么样的条件,就Sharding到什么服务器上面。但是让每一个业务系统去做的成本是非常高的,一定要有一个中间通用的东西,能够解决数据库水平拆分的问题。

阿里电商架构演变之路_第5张图片

所以我们开发了一套数据库的中间件叫TDDL。TDDL就是在中间件层面支持数据库的水平拆分,业务就是在写单库一样,你不需要感知太多的东西,但是我已经把数据分散到各个数据库里面去了。当时还有一个系统是CORONA,CORONA今天我们已经把他放到云上面去了,它遵循标标准的JDBC协议,应用在写代码的时候还是遵循标准的JDBC协议,完全不需要感知任何的东西,用的也是标准的JDBC包。把请求送到我们的server上面,server去做Sharding处理,整个对应用是完全没有感知的。 

3.4.3 MQ集群

例如,我要创建一个订单,订单后面依赖了200多个系统,如果按照同步调用一步步进行下去,可能最终返回的返回时间会非常长,这时候怎么办呢?我们会选择并发,A去调用B、去调用C、去调用D的这种HSF直接调用。但这时存在一个问题,如果说下游依赖的200多个系统中有一个系统被挂起了,就使整个请求被挂起了,然后接下来就很难进行了,而且这时如果对方的系统出现了严重的问题,会使我后续的请求都被挂起,最终也会把我的系统拖垮。这个时候我们需要一个异步解耦的方式,那么就产生了消息中间件。消息中间件就是当A要去调用的时候,然后就会发一个消息,然后下游的系统开始订阅这条消息,各自去处理各自的,处理完之后把结果返回给中间件,这样就完成了异步通信过程。那么如果其中某一个系统发生了问题,前端的交易系统创建订单的时候,它只要把消息发出去就不用管了,等所有的事情都处理完再回调它就可以了,就不会关注你如何调用。

阿里电商架构演变之路_第6张图片

3.4.4 分布式追踪

随着我们整个分布式架构的演进,架构变得异常复杂,依赖关系也变得异常复杂。这时候我们就想能不能可视化线上的问题,方便我们知道究竟发生了什么、它们之间的调用关系和调用链路是什么样。于是乎就产生了分布式追踪(EAGLEEYE)。有了EAGLEEYE,我们就能清楚地知道一个请求过来,是怎么样从入口一直传递到最后,中间都经历了什么,然后哪一块可能是有问题的。像图中这样报错位置会标红,我们就可以清晰的知道是哪个系统出的问题。我们不需要再像以前一样,大家各在排查自己的系统,导致我们处理问题的时间比较长。

阿里电商架构演变之路_第7张图片

3.4.5 其它系统

愚公:有了分库分表,我们如何把oracle的数据迁移到MySQL?对此,我们开发了几个中间件,第一个就是“愚公”,把oracle里面的数据通过“愚公”一点一点地迁移到MySQL里面去,放到各个库里面,同时保证我们的业务不受影响。

精卫:当我们把数据库做分库分表之后,我们还需要在数据库和缓存之间做一些trigger,当数据变了,需要触发一个事件,可能以前我们需要通过写一个程序来实现,现在我们也沉淀了一套中间件系统——精卫,它会监听每个数据库的变化,当数据库每个记录发生变化之后,它就触发一个事件,接听到这个事件之后,业务方可以根据自己的业务需求写一个精卫的worker,然后放到精卫里面去,触发相应的逻辑。最典型的就是触发cache逻辑。随着我们IDC架构之后,当我们的数据在单点写完之后,其他的地域如何感知到数据的变化呢?就是通过精卫这样一个系统实现的。当数据库变化了,精卫会触发失效cache,当业务请求再过来的时候,就会把cache里面的数据填充成最新的数据,然后能够让业务看到最新的数据,就不会出现当A单元数据变动了,然后B单元和C单元的cache没有生效的情况。

 

第四章 淘宝4.0

4.1 3.0架构遇到的问题

资源中最重要的问题就是资源受限,当我们的机房都在一个地方,这个地方并不能无限扩展,随着我们服务器数量越来越多,那么这个地方可能就放不下我们的服务器。比如2013年我们买到机器之后,杭州的机房没有地方去放。随着我们搞双十一活动,伴随着销售额和秒级峰值都有很大的提升,我们的成本也会有一定的提升,我们最终也会遇到单地域资源的限制;第二个是扩展性,有些业务可能不能只在这一个地方部署,因为别人访问我会比较慢,需要部署到国外,这时候业务有一个异地部署的需求;第三个就是一个容灾的需求,毕竟天灾人祸都在所难免。比如说同样是在2013年,杭州是40度的高温,我们的机房差点被限电,还好最终没有限。但是这也给了我们一个警示,就是我们必须要对我们的架构进行演进。如果不演进的话,总有一天我们的资源会不够。

阿里电商架构演变之路_第8张图片

4.2 4.0结构

架构演进就是不把鸡蛋放到同一个篮子里面,我们开始把我们的业务划分出各个逻辑的单元,可以把它们放到各个地方,然后让我们整个系统分散到全球,各个系统之间也没有过强的依赖,当某一个地域出现问题之后,不会影响到其他地方,我们只需要把流量切换一下就可以。现在我们应用的就是这套架构。

们按照业务的维度,把业务划分成各个逻辑单元。比如说第一个要做单元化的是交易单元,我们就把整个交易链路划分出来,放到各个逻辑单元里面,然后在水平方向上进行拆分,然后把数据再在水平上做一个区分。单元内的数据就不要发跨单元。如果跨单元就会出现一些问题,比如说容灾问题,如果A挂掉之后,可能不止影响到A,其他单元也会受到影响。如果发生跨单元调用,延时也会比较长,对于最终用户下单的体验也是非常差的。所以我们要遵循单元封闭的逻辑,让每一个单元内的调用关系都封闭在自己的单元内,不要发生跨单元。

阿里电商架构演变之路_第9张图片

在技术架构上,我们对技术做了一个分层,并且定了几个原则,除了单元封闭原则之外,还有全局路由,全局路由解决的是全局用户流量的分配,当一个用户流量进来之后,它会按照我们的路由规则分配到相应的单元里面去。当用户流量进来,会跳到CDN,CDN知道其属于哪个单元。然后到了某一单元之后,接入层会判断其是否属于这个单元,如果不属于,会让其跳到正确的单元里面去。如果属于这个单元就继续往下走,直到走到数据库这一层。如果数据库这一层出现了问题,我们做的是数据库写失败,也不能够让其写成功,所以数据要一致。这时候对于数据一致又出现了新的问题,比如说我们按照买家订单写到各个单元里面,但是卖家如何发货呢?卖家其实是放到各个中心里面的,买家的所有下单数据都要同步到卖家这里。我们的模式就是最终一致性,就是对时间不是很敏感,我可以慢慢的同步,比如说,买家下了单,过了一两秒之后才能同步到卖家那里,其实这个时间是大家都能够接受的。对于强一致类型的数据,我们就跨单元,在同一个地点去捡数据。就是图上面红色部分——强中心依赖,所以这是我们交易链中核心——跨单元依赖。 

阿里电商架构演变之路_第10张图片

个人凭感觉总结一下,拿购物的过程举个例子,正好也与上面的图符合:

首先水平进行了拆分,可以看到拆分成了不同的单元,每个单元里面有所有的商品数据,还有买家的个人数据,这样用户进行浏览商品目录,查看详情,下单等等所有的操作就可以局限在这一个单元里了,然后我们将这一个单元部署到北京,北京的用户就不用访问杭州的服务器了,直接访问北京的服务器就可以解决所有问题了。

基本逻辑是这样的,但是有这样几个问题,首先就是用户下单后,数据在北京的单元,另一个用户下单后数据在杭州的单元,商家该怎样知道到底多少人购买了呢,一般会搞一个中心单元,如上图所示,中心单元存储着所有买家下单的数据还有如卖家的全量数据、商品的全量数据,不同的单元会更新中心单元的数据,当买家在北京下单后,除了更新本单元,也会更新中心单元,这样从中间单元就知道买家的情况,然后根据买家发货了。至于更新中心单元是不是同步的就不清楚了,感觉不是同步的,上面隔一两秒才同步到卖家那里的意思感觉就是通过MQ这种异步同步到数据中心,但是要确保异步同步成功,不然一个北京单元挂了,北京用户一看我刚下的单怎么没了。

还有一些关键数据,如用户钱包余额、商品库存,这些所有单元都需要用的,也需要强数据一致性的,就都放在中心单元里,每个单元都取中心单元拿,不保存在私有单元里,对应上图的强中心依赖。

这就是我们整个异地多活的架构,异地多活解决的就是容灾问题、资源问题还有业务的扩展性问题。只要我们发现资源不够了,我们只需要创建一个新的单元,就可以把容量扩上去。首先调用就把资源统一了,建站平台通过调用就可以快速搭建一个单元。当这个单元通过全链路压测之后,我们整个单元就可以通入使用,这样容量的问题就得到了解决。那么容灾的问题通过全局路由就可以解决。当某个单元出了问题之后,我们只要快速的把流量切换出去就可以。业务扩展性是整个架构天然具备的,我们已经在千里之外把这个单元部署过了。

 

阿里电商架构演变之路_第11张图片

后面有一点内容说了下全链路压测和高可用,这个内容不多,本人也不大熟,就没写,感兴趣的可以打开博客开头的地址自己去看看。

 

 

第五章 新起点

为什么没有淘宝5.0,而要叫新起点呢?我想是因为年轻人不讲5的,阿里的团队2017年就预言到2020年要发生的事情,真是佩服佩服(狗头)。

云会变成如同水电煤一样的基础资源,越来越多的业务会在云上展现,这些业务中会有很多经历如同淘宝一样的发展,我们将加速这些业务的发展进程,创造更大价值,用技术驱动业务,把我们的技术能力输出到云上去。

现在我们不只服务于我们的双十一,我们也想为其它企业提供技术服务,用技术驱动他们,让他们也能只关心业务就好,不用去过多的关心底层是如何实现的。上面是一些在云端的产品,在阿里云上可以直接看到,像DRDS、EDAS、MQ等。

现在整理阿里的架构叫Aliware。Aliware已经在云上为企业提供企业级的互联网架构,支持了很多的企业。

阿里电商架构演变之路_第12张图片

分析:

这个就是说了云化,其实上面提到了很多中间件,如MQ、RPC、分布式数据库中间件、文件服务器等等,这种其实每个大项目都要用到的,每一个系统都搭建个集群就比较麻烦,可以抽出来组成一套系统,也就是所谓的云,不但可以更加专业化,还可以提供给各种不同的项目,甚至别的企业项目,让开发人员只需专注于业务的实现。据说淘宝很多都已经上云了,好像比较重要的支付系统也上云了,这个就不大清楚了,有感兴趣的可以自己去看看哈。 

个人还是挺喜欢的,我之前还自己搭了一套RocketMQ集群,现在一想感觉血亏,有点浪费时间,还不如搞套阿里云上的,方便也没几个钱,溜了溜了。

 

 

 

你可能感兴趣的:(后台架构设计,架构,淘宝,电商)