当前位置: 首页 > 科技观察

支付宝坚定支持双11和双12的核心架构设计

时间:2023-03-16 01:37:58 科技观察

1.前言我还依稀记得去年双11在支付宝作战室。峰顶曲线缓缓攀升,最后变得极为陡峭。值班室的同学们兴奋不已,欢呼声顺着攀升曲线攀升至高峰,每秒58.3万笔交易,同样刷新了交易高峰记录,但与往年相比。翻了一番,涨了30%到40%,增速还是小很多。2010年双十一支付的峰值是每分钟2万笔,到2017年双11变成每秒25.6万笔,然后是去年的每秒58.3万笔,是首届双十一的千倍以上2009年11.为了承受这么大的支付TPS,蚂蚁做了大量的顶层架构设计和底层实现优化,其中最核心的就是LDC架构。2、什么是LDCLDCCLDC的全称:LogicDataCenter,逻辑数据中心,之所以叫LDC,是相对于传统的IDC(InternetDataCenter)提出的一个概念。IDC相信大家都很清楚,它是一个物理数据中心。说白了就是可以建网站的物理机房。LDC(LogicalDataCenter),核心的架构思想就是不管你的物理机房怎么部署,比如你可能有3个IDC,分别位于两个不同的城市(常说的两地三中心),它们在逻辑上是统一的。我从逻辑上看是一个整体,统一协调部署。3、为什么会出现LDC?1.架构演进LDC解决什么问题?我们必须从架构的演变开始。我们用一个特定的应用来推导一次。1)单体应用架构首先看下图所示的单体应用架构。请求走网关接口,网关接口直接调用应用或服务,服务调用存储层查询或写入数据。这种架构模式最大的风险是服务和存储是单点的。访问容量和性能受限于存储和应用程序的容量和性能。在容灾方面,一旦发生故障,只能等待单点应用或存储的恢复。.2)分布式架构后来工程师开始横向拆分应用,纵向拆分服务。水平拆分大家应该不陌生,就是增加服务器,在每台服务器上部署实例。垂直拆分是按域拆分服务。例如,一个交易系统有商户域、商品域、用户域和订单域。拆分成多个微服务,服务解耦,服务可以独立发布,应用的复杂度会更高。这种分布式架构解决了单点服务的问题。如果一台服务器宕机了,服务还是可以的,但是存储层还是单点的,而且随着业务的增长,扩容加入的机器越多,大家发现查询写入效率需要时间才能达到到某个阶段,速度变慢,分析表明存储层存在性能瓶颈。上图中只用了2台服务器连接数据库。在一个真正的分布式系统中,可能有数百甚至数千台服务器。如果都连接到一个DB,连接数、锁争用等问题都会拖慢SQL性能。知道。3)读写分离架构后面的事情大家都知道了。互联网公司开始读写分离,把读请求和写请求分开。读写分离隐含了一个逻辑,就是数据写入后,不会立即使用。正在写入的数据和立即使用的数据之间存在时间间隔,直到从数据库同步数据后才会读取数据。实际统计表明,在常规应用中,90%的数据写入后不会立即使用。当然,我这里说的即时时间单位是ms,一般的同步延时都是几毫秒,不会超过10~20ms。4)分库分表的分布式架构但是这种架构并没有解决写的问题。随着业务量的增长,写入数据成为瓶颈。分库分表应运而生,分库分表的中间件开始流行,现在基本已经成为中大型互联网公司的标配。基本思想是按照指定的维度对数据进行拆分。更常见的是userId维度。比如取userId的后2位,可以拆分成几百个数据库和表,或者除以指定的模取余数,比如除以64得到余数即可根据余数范围0-63拆分为64个库。关于分库分表,很多人知道有垂直拆分和水平拆分两种(上面说的垂直和水平是系统的拆分,这里指的是存储),垂直拆分就是拆分根据业务维度,将相同业务类型的表归为一个库,往往按照领域模型的概念进行拆分,比如订单库、用户库、商品库等。水平拆分就是对一张数据量大的表进行拆分(库)成很多数据量小的表(库)可以减少库和表的访问压力。可以类比为系统的横向和纵向切分:为什么叫横向和纵向?其实很好理解。你想象一个用户表,里面有很多字段,如下图:垂直拆分就是从中间垂直画刀,把右边蓝色的用户信息表和绿色的订单信息表拆分成2张桌子。库分为用户库和订单库。水平拆分就是做水平切分,减少数据量。看到这里,是不是觉得问题已经解决了呢?经过上面的分库分表,如果应用层面能搞定的话,数据库层面确实可以做到万并发的水平。但是再增加一个数量级的容量就有点困难了。5)单元化分布式架构因为一个库实例是所有应用共享的,即每增加一台机器,数据库连接数就会相应增加,增量至少为机器设置的最小连接数。①为什么应用需要连接所有的数据库实例?网关层的流量可能会到达任何服务器。比如用户A的请求到达服务器,服务器必须有用户A的userId片段的数据库连接。否则,流量将被路由或执行失败。分库分表只是解决了单库单表的访问压力问题,但是由于每台服务器同时连接了所有的分库实例,所以到一定阶段就没有进一步扩容了,因为有瓶颈是数据库实例的连接数。②数据库出现瓶颈怎么办?相信聪明的已经猜到了,那就是在应用层隔离userId分片,在网关层路由流量时,将指定uid分片的流量路由到指定的应用单元,内部消化了这个应用单元的流量,如下图:比如uid=37487834,最后两位是34,属于00-49范围,那么用户流量直接路由到应用组00-49,所有的数据交互都在这个单元操作中完成。这样,uid00-49分组单元中的应用只使用userId00-49分库连接的数据库,uid50-99分组单元的应用也是如此。数据库的连接数直接减半,而且还可以拆分单元,现在是2个单元,最多可以拆分100个单元。单位是LDC中的核心概念。下面着重介绍一下单位这个词的具体含义。Ant中的单元有一个名字叫做Zone,Zone中部署了一个完整的服务。例如,用户可以在一个Zone中完成一套完整的业务流程,流量不需要其他Zone提供服务,有能力完成一套完整的服务。一整套服务可以在一个Zone中完成,在逻辑上是自成一体的。这样做有什么好处?如果一个Zone发生故障,路由层会直接将Zone的流量转移到其他的Zone上,其他接受该Zone流量的Zone可以分担流量和分配流量,非常方便。2.AntZone下图是AntZone按照region和userId分片的部署架构示意图。进行了一些简化。实际的Zone部署单元会稍微复杂一些。上面介绍的Zone能够在uid维度完成一套完整的业务流程。应用程序相互依赖的服务均由该Zone提供,服务之间的调用均在该Zone内完成。但是如果你聪明的话,你可能会想到一个问题。部分数据无法按照userid维度进行拆分。怎么可能全球只有一份呢?比如配置中心的数据是集中存储的。.实际上,在Ant内部,存在三种类型的区域:RZone、GZone和CZone。RZone:上面提到的逻辑是自成一体的,是业务系统整体部署的最小单元。可以按照userId维度拆分的服务和库部署在RZone中。GZone:GZone是一个全局区域。听名字就知道,GZone的服务和库,全球只会部署一份。一定是在某个机房,也会部署在其他地方,但是只是为了容灾,不会启用。CZone:CZone比较有意思。为什么会有CZone?它的创建是为了解决GZone的缺点。上篇《从B站崩了看互联网公司如何做好高可用》架构的文章提到过,跨城通话因为距离远很费时间。如果GZone在上海的服务部署,杭州机房的服务需要使用GZone部署的服务,只能跨城市、跨机房调用。很有可能一个服务有很多rpc调用,会消耗很多时间,那怎么办呢?搭建城市之间的数据同步桥梁,CZone扮演桥梁的角色,负责在城市之前同步GZone的数据,C代表城市。也正是因为我前面提到的“读写时差现象”,写入GZone的数据允许有一定的延迟,将CZone同步到其他CZone。