蚂蚁金服支付宝系统的单元化(转载)

蚂蚁金服支付宝系统的单元化java

在当今的互联网业内,很多人对“单元化”这个词已经耳熟能详。不少大型互联网系统,诸如阿里系的淘宝、支付宝、网商银行等,都已经实现了单元化架构,并从中获益匪浅。还有更多的公司,或在规划着本身的系统架构向单元化演进,或已经在单元化的建设过程当中。git

单元化架构能给系统带来什么样的能力,又会带来哪些额外的成本,该不应决定作单元化,要作的话应该怎么作。本文用蚂蚁金服支付宝系统的单元化架构建设实践,为你们勾勒一下单元化的肢体骨架和细枝末节。github

2、为何要作单元化

决策一个系统的总体架构方向,将对这个系统的将来产生深远影响,而且会有实际的技术改造方面的人力投入。这样的的决策必须是谨慎的,有依据的。因此,对于要不要单元化这个问题,这里最想告诉你们的是一个忠告:切勿神话单元化。数据库

回顾支付宝的整个单元化历程,最初促成这个决策的缘由是一件看似无关的事情。早在 2011 年,支付宝系统就开始对核心数据库作水平拆分,而更早以前,对多个关键业务数据库的垂直拆分就已完成。到了 2013 年时,几乎全部支付宝核心数据库,都完成了水平拆分,拆分维度为用户,拆分为 100 个数据分区。此时系统的部署模式是这样的:服务器

image

同一个应用的全部节点,都会链接这个业务的全部数据分库,每一个分库上部署了若干数据分区。任意一个应用节点均可能接收到来自任意用户的业务请求,而后再根据数据分区规则,访问对应分库的数据。网络

这个架构帮助支付宝系统撑过了 2012 年双 11,却不管如何过不了 2013 年大促了,缘由在于数据库链接不够用了。主流的商业数据库,链接都不是共享的,就是说一个事务必须独占一个链接。而链接却又是数据库很是宝贵的资源,不能无限增长。当时的支付宝,面临的问题是不能再对应用集群扩容,由于每加一台机器,就须要在每一个数据分库上新增若干链接,而此时几个核心数据库的链接数已经到达上限。应用不能扩容,意味着支付宝系统的容量定格了,不能再有任何业务量增加,别说大促,极可能再过一段时间连平常业务也支撑不了了。 若是 OceanBase 在当时已经成熟,能够很好的解决 Sharding 带来的链接数瓶颈问题,由于 OceanBase 是分布式数据库,链接能够共享。然而那时并无一个合适的通过验证的共享链接数据库产品,所以单元化成为了最好的也是惟一的解决办法。架构

image

根据单元化的特性,每一个单元中的应用服务器仅链接本单元的数据分库,若是有 n 个单元,这就至关于全部数据分库的链接数马上降为原来的 1/n。框架

从支付宝并无倒在 2013 年双 11 能够知道,此次架构改造是成功的,解决了当初的燃眉之急,而且在落地单元化架构的过程当中,蚂蚁技术团队也充分拓展了单元化架构的应用场景和架构的能力,从中得到了更多的架构红利,主要表如今如下几个方面:运维

无限可伸缩微服务架构

经过中间件和 PaaS 平台的配合,可以经过快速搭建一个业务完整的逻辑部署单元对系统进行总体扩容,对新机房扩容等操做带来了很是大的便利。突破接入层、应用层和数据层的瓶颈,可支持无限扩展。分布式

异地多活部署

除了具有异地容灾能力之外,还能作到异地多城市多活,可随时在多个城市间调配流量比例,在提高容灾能力的同时,下降了成本。

全站蓝绿发布和线上灰度仿真

经过多单元之间灵活的流量调配机制,能够实现大规模集群的蓝绿发布,极大的提高了发布效率。同时,经过单元内自包含的服务发现/路由和数据层的单元化分片,保证故障被切割的更小且具有独立性,不会传播到其余机房,从而实现发布时的故障自包含,蚂蚁基于这个机制实现了线上全链路压测和灰度仿真环境,为业务提供了更真实的验证环境,这对充分验证业务正确性,下降技术故障起到了关键的做用,尤为对金融类业务。

异构机房上的弹性混合云架构

经过单元化伸缩的机制和容器化技术对底层虚拟化平台的屏蔽,实现多个异构机房的资源充分利用,不管基于什么架构,不管在哪一个城市,均可以快速建站部署单元,并在业务高峰期事后快速回收,完成数据的回迁。

虽然结果很好,整个单元化演进的过程也是极其艰辛的。在关键业务数据库都已经水平拆分完毕的状况下,支付宝仍是用了将近 1 年的时间,改造了几乎全站业务系统以支持单元化。除此以外,还花费了至关大的力量改造系统使用的各种中间件,包括微服务框架、消息中间件、调度系统等,还建设了专门的单元化运维监控平台。不管在架构方案上仍是技术产品上,蚂蚁技术团队都积累了大量的经验。

这个过程带来的启示是,单元化确实能带来很多激动人心的特性,但同时也会让系统架构变的复杂。这不只会对系统的运维平台提出更高要求,也会给业务研发带来一些理解成本,这个思想很是像业界流行的 Cloud Native 的思想,要充分利用云架构的好处,还须要让应用层架构设计遵守必定的范式,而蚂蚁逐步将这些范式和能力沉淀到了 PaaS 平台、中间件和数据库中,成为一种原生 (Native) 的能力,为业务开发提供单元化能力支撑。

因此说,单元化不能被神话,它有利有弊,只是看着它的好处就贸然决定开始的作法不可取。应当充分评估当前的系统现状,识别其中存在的和潜在的问题,判断单元化是否能解决以及解决所带来的成本,选择最合适的性价比最高的架构来支撑业务发展。 固然,若是最后的判断是须要引入单元化,那么必定义无反顾,毕竟它产生的价值及其诱人。

3、能不能单元化

若是您是新建一套系统,那么恭喜你,你只要考虑这个系统的重要性,即未来是否须要在可扩展性、容灾能力、业务连续性、成本控制等方面有很高的要求,若是答案是确定的,那能够一开始就按照单元化的方式去设计,这套架构彻底能支持业务从单机房到同城多机房,再到异地多活机房的平滑演进。但若是是一套老系统,就须要评估一下它是否具有单元化的基础了。

所谓单元,是指一个能完成全部业务操做的自包含集合,在这个集合中包含了全部业务所需的全部服务,以及分配给这个单元的数据。单元化架构就是把单元做为系统部署的基本单位,在全站全部机房中部署数个单元,每一个机房里的单元数目不定,任意一个单元都部署了系统所需的全部的应用,数据则是全量数据按照某种维度划分后的一部分。 传统意义上的 SOA 化(服务化)架构,服务是分层的,每层的节点数量不尽相同,上层调用下层时,随机选择节点。

image

单元化架构下,服务仍然是分层的,不一样的是每一层中的任意一个节点都属于且仅属于某一个单元,上层调用下层时,仅会选择本单元内的节点。

image

一个单元,是一个五脏俱全的缩小版整站,它是全能的,由于部署了全部应用;但它不是全量的,由于只能操做一部分数据。可以单元化的系统,很容易在多机房中部署,由于能够轻易的把几个单元部署在一个机房,而把另外几个部署在其余机房。借由在业务入口处设置一个流量调配器,能够调整业务流量在单元之间的比例。

image

从这个对单元的定义和特性描述中,能够推导出单元化架构要求系统必须具有的一项能力:数据分区,实际上正是数据分区决定了各个单元可承担的业务流量比例。数据分区(shard),便是把全局数据按照某一个维度水平划分开来,每一个分区的数据内容互不重叠,这也就是数据库水平拆分所作的事情。 仅把数据分区了还不够,单元化的另一个必要条件是,全站全部业务数据分区所用的拆分维度和拆分规则都必须同样。如果以用户分区数据,那交易、收单、微贷、支付、帐务等,全链路业务都应该基于用户维度拆分数据,而且采用同样的规则拆分出一样的分区数。好比,以用户 id 末 2 位做为标识,将每一个业务的全量数据都划分为 100 个分区(00-99)。

有了以上两个基础,单元化才可能成为现实。把一个或几个数据分区,部署在某个单元里,这些数据分区占总量数据的比例,就是这个单元可以承担的业务流量比例。 选择数据分区维度,是个很重要的问题。一个好的维度,应该: 粒度合适。粒度过大,会让流量调配的灵活性和精细度收到制约;粒度太小,会给数据的支撑资源、访问逻辑带来负担。 足够平均。按这个维度划分后,每一个分区的数据量应该几乎一致。 以用户为服务主体的系统(To C),好比支付宝,一般能够按照用户维度对数据分区,这是一个最佳实践。

4、怎么作单元化

在真正动手以前,有一个必需要知晓并始终记之在心的事实,完美的单元化是不存在的。 从单元化的角度,在一个系统当中实际上存在 3 类数据:

可分区数据

能够按照选择好的维度进行分区的数据,真正能被单元化的数据。这类数据一般在系统业务链路中处于核心位置,单元化建设最重要的目标实际上就是把这些数据处理好。好比订单数据、支付流水数据、帐户数据等,都属于这一类型。 这类数据在系统中的占比越高,总体单元化的程度就越高,若是系统中所有都是这样的数据,那咱们就能打造一个完美单元化的架构。不过现实中这种状况存在的可能性几乎为零,由于下面提到的两类数据,或多或少都会存在于系统当中。

全局数据,不被关键链路业务频繁访问

不能被分区的数据,全局只能有一份。比较典型的是一些配置类数据,它们可能会被关键链路业务访问,但并不频繁,所以即便访问速度不够快,也不会对业务性能形成太大的影响。 由于不能分区,这类数据不能被部署在经典的单元中,必须创造一种非典型单元用以承载它们。

全局数据,须要被关键链路业务频繁访问

乍看与上面一类类似,但二者有一个显著的区别,便是否会被关键链路业务频繁访问。若是系统不追求异地部署,那么这个区别不会产生什么影响;但若是但愿经过单元化得到多地多活的能力,这仅有的一点儿不一样,会让对这两类数据的处理方式大相径庭,后者所要消耗的成本和带来的复杂度都大幅增长。

究其缘由是异地部署所产生的网络时延问题。根据实际测试,在网络施工精细的前提下,相距约 2000 千米的 2 个机房,单向通讯延时大约 20ms 左右,据此推算在国内任意两地部署的机房,之间延时在 30ms 上下。假如一笔业务须要 1 次异地机房的同步调用,就须要至少 60ms 的延时(请求去,响应回)。若是某个不能单元化的数据须要被关键业务频繁访问,而业务的大部分服务都部署在异地单元中,网络耗时 60ms 的调用在一笔业务中可能有个几十次,这就是说有可能用户点击一个按钮后,要等待数秒甚至数十秒,系统的服务性能被大幅拉低。

这类数据的典型表明是会员数据,对于支付宝这类 To C 的系统来讲,几乎全部的业务都须要使用到会员信息,而会员数据却又是公共的。由于业务必然是双边的,会员数据是不能以用户维度分区的。

支付宝的单元化架构中,把单元称之为 “zone”,而且为上面所说的3类数据分别设计了三种不一样类型的 zone:

  • RZone(Region Zone):最符合理论上单元定义的 zone,每一个 RZone 都是自包含的,拥有本身的数据,能完成全部业务。
  • GZone(Global Zone):部署了不可拆分的数据和服务,这些数据或服务可能会被RZone依赖。GZone 在全局只有一组,数据仅有一份。
  • CZone(City Zone):一样部署了不可拆分的数据和服务,也会被 RZone 依赖。跟 GZone 不一样的是,CZone 中的数据或服务会被 RZone 频繁访问,每一笔业务至少会访问一次;而 GZone 被 RZone 访问的频率则低的多。

image

RZone 是成组部署的,组内 A/B 集群互为备份,可随时调整 A/B 之间的流量比例。能够把一组 RZone 部署的任意机房中,包括异地机房,数据随着 zone 一块儿走。

GZone 也是成组部署的,A/B 互备,一样能够调整流量。GZone 只有一组,必须部署在同一个城市中。

CZone 是一种很特殊的 zone,它是为了解决最让人头疼的异地延时问题而诞生的,能够说是支付宝单元化架构的一个创新。 CZone 解决这个问题的核心思想是:把数据搬到本地,并基于一个假设:大部分数据被建立(写入)和被使用(读取)之间是有时间差的。

  • 把数据搬到本地:在某个机房建立或更新的公共数据,以增量的方式同步给异地全部机房,而且同步是双向的,也就是说在大多数时间,全部机房里的公共数据库,内容都是同样的。这就使得部署在任何城市的 RZone,均可以在本地访问公共数据,消除了跨地访问的影响。整个过程当中惟一受到异地延时影响的,就只有数据同步,而这影响,也会被下面所说的时间差抹掉。

  • 时间差假设:举例说明,2 个用户分属两个不一样的 RZone,分别部署在两地,用户 A 要给用户 B 作一笔转帐,系统处理时必须同时拿到 A 和 B 的会员信息;而 B 是一个刚刚新建的用户,它建立后,其会员信息会进入它所在机房的公共数据库,而后再同步给 A 所在的机房。若是 A 发起转帐的时候,B 的信息尚未同步给 A 的机房,这笔业务就会失败。时间差假设就是,对于 80% 以上的公共数据,这种状况不会发生,也就是说 B 的会员信息建立后,过了足够长的时间后,A 才会发起对 B 的转帐。

经过对支付宝 RZone 业务的分析发现,时间差假设是成立的,实际上超过 90% 的业务,都对数据被建立和被使用之间的时间间隔要求很低。余下的那些不能忍受时间差的业务(即要求数据被建立后就必须立刻可用,要不就干脆不能访问),则必须进行业务改造,忍受异地访问延时。

5、须要哪些支持

前面提到,支付宝系统早已实现了数据水平拆分,而且全站拆分维度一致,在具有了这个重要基础能力的前提下,仍然举全站之力用了近一年时间才完成单元化改造,除了由于要改造业务系统以妥善处理 GZone/CZone 的数据之外,还有一项工做也耗费了大量人力和时间,那就是建设起了一个单元化技术支持平台。 单元化架构增长了构复杂性和运维复杂度,若是没有这样一个平台支撑,很难把如此复杂的一个系统健康的维护起来。 所谓单元化技术支持平台,至少应该包含三方面功能。

一套支持单元化的中间件

支付宝的业务开发因单元化架构而变得复杂、不易理解,而实际上如今看到的复杂性比起它的本来的程度来讲已经下降了太多。这其中最大程度屏蔽了单元化细节,让单元化架构尽可能对业务层透明,起到相当重要做用的,就是一整套专门针对单元化而研制的中间件,也即上文提到的原生 (Native) 单元化能力。

比较关键的几个包括,数据访问层中间件,把数据水平分库分表的细节隐藏在水面之下,上层业务使用起来跟单库单表没什么区别。更进一步的,数据访问层能实时动态感知单元化分流规则,根据规则变化决策是否链接某个数据分库,以及一笔业务是否容许访问某个数据分库。能够说单元化的本质就是对数据的逻辑隔离,有这样一个数据访问中间件对单元化建设来讲是必不可少的,它解耦了业务层对数据层结构的依赖,大大下降了理解成本。

另外更为重要的是几个负责信息传递的中间件,正是它们让单元能够成为单元。这其中有微服务框架、消息中间件等,它们可以根据单元化规则把系统应用间的服务调用或消息流转约束在一个逻辑区域内,再配合上数据访问中间件对数据访问的约束,就让这一个个逻辑区域造成了一个个单元。若是有些调用必须跨单元发生,也由它们根据规则执行转发,不须要业务层关心。

一个规则管理和流量调拨系统

前面屡次提到了“规则”这个词,在单元化架构中,规则举足轻重,业务流量在单元间怎么分配,哪一个单元能访问哪一个数据分库,某次服务调用可否跨出单元,这些都由规则掌管。可想而知,必须有一个统一的位置来全局惟一的管理这套规则,并在变动时可以及时准确的的推送给各个执行点,不然不一样模块识别到的规则不一样,将会形成全系统信息混乱。

规则管理系统的目的就是成为这样一个单元化规则权威持有者,运维人员对规则的全部变动,都在这个系统上操做。它经过某种协议链接着系统中全部须要感知规则的模块,一旦发生规则变化就实时把新规则内容推送给各个模块,并识别推送结果,对推送失败的模块执行重试,确保规则下发到全部位置。

一个面向单元的发布部署和监控平台

单元化后,一个系统被划分红了数量众多的逻辑单元,这让系统发布换版的粒度更细,试错成本更低,但也让发布这件事情更难作,因此一个能面向单元进行发布的部署平台就变的很是必要。 这个部署平台可以以单元为维度执行发布,单元间能够互不影响的独立部署。

同时,平台须要有能力统一编排和控制不一样单元的部署进程,从而可以实现基于单元的全站蓝绿发布等高阶功能。

此外,监控系统要求可以细化到单元粒度展现监控信息和发送报警,以协助判断每一个单元中的系统健康程度,为快速执行流量切换以隔离故障等操做提供依据。

以上几项是一个单元化技术支持平台必需要具有的能力,在支付宝的单元化进程中,已经沉淀出了完整的这样一套平台,并在逐步产品化为具有完整单元化能力的 SOFA 平台和 OceanBase 数据库,搭载在蚂蚁金融云上对外输出。在几年中前后支持了蚂蚁保险、网商银行的单元化改造,在将来也将为更多的金融生态合做伙伴提供服务。

转自做者: chenshiying007

相关文章
相关标签/搜索