当前位置: 首页 > 分布式系统 > 正文

分布式交易设计

1 星2 星3 星4 星5 星 (暂无评分)
Loading ... Loading ...
baidu_share

最近在搞交分布式交易系统,主要是双机房系统双活。在网上查了一些资料,infoq对阿里巴巴毕玄访谈:异地多活数据中心项目的来龙去脉。作者对分布式交易系统理解很深刻,访谈内容摘抄过来,供自己学习用。

首先请介绍一下数据中心异地多活这个项目。

毕玄:这个项目在我们内部的另外一个名字叫做单元化,双活是它的第二个阶段,多活是第三个阶段。所以我们把这个项目分成三年来实现。所谓异地多活,故名思义,就是在不同地点的数据中心起多个我们的交易,并且每个地点的那个交易都是用来支撑流量的。

当时为什么要做这件事呢?

毕玄:其实我们大概在2009还是2010年左右的时候,就开始尝试在异地去做一个数据中心,把我们的业务放过去。更早之前,我们做过同城,就是在同一个城市建多个数据中心,应用部署在多个数据中心里面。同城的好处就是,如果同城的任何一个机房挂掉了,另外一个机房都可以接管。

做到这个以后,我们就在想,异地是不是也能做到这样?

整个业界传统的做法,异地是用来做一个冷备份的,等这边另外一个城市全部挂掉了,才会切过去。我们当时也是按照这个方式去尝试的,尝试了一年左右,我们觉得冷备的方向对我们来讲有两个问题:第一个问题是成本太高。我们需要备份全站,而整个阿里巴巴网站,包括淘宝、天猫、聚划算等等,所有加起来,是一个非常大的量,备份成本非常高。第二个问题是,冷备并不是一直在跑流量的,所以有个问题,一旦真的出问题了,未必敢切过去。因为不知道切过去到底能不能起来,而且整个冷备恢复起来要花多长时间,也不敢保证。因此在尝试之后,我们发现这个方向对我们而言并不好。

那为什么我们最后下定决心去做异地多活呢?

最关键的原因是,我们在2013年左右碰到了几个问题。首先,阿里巴巴的机房不仅仅给电商用,我们有电商,有物流,有云,有大数据,所有业务共用机房。随着各种业务规模的不断增长,单个城市可能很难容纳下我们,所以我们面临的问题是,一定需要去不同的城市建设我们的数据中心。其次是我们的伸缩规模的问题。整个淘宝的量,交易量不断攀升,每年的双十一大家都看到了,增长非常快。而我们的架构更多还是在2009年以前确定的一套架构,要不断的加机器,这套架构会面临风险。

如果能够做到异地部署,就可以把伸缩规模缩小。虽然原来就是一套巨大的分布式应用,但是其实可以认为是一个集群,然后不断的加机器。但是在这种情况下,随着不断加机器,最终在整个分布式体系中,一定会有一个点是会出现风险的,会再次到达瓶颈,那时就无法解决了。

这两个问题让我们下定决心去做异地多活这个项目。

为什么我们之前那么纠结呢?因为整个业界还没有可供参考的异地多活实现,这就意味着我们必须完全靠自己摸索。而且相对来讲,它的风险以及周期可能也是比较大的。

这个项目具体是怎样部署的?

毕玄:以去年双十一为例,当时我们在杭州有一个数据中心,在另外一个城市还有个数据中心,一共是两个,分别承担50%用户的流量。就是有50%的用户会进入杭州,另外50%会进入到另外一个城市。当用户进入以后,比如说在淘宝上看商品,浏览商品,搜索、下单、放进购物车等等操作,还包括写数据库,就都是在所进入的那个数据中心中完成的,而不需要跨数据中心。

这样的优势是?

毕玄:异地部署,从整个业界的做法上来讲,主要有几家公司,比如Google、Facebook,这两家是比较典型的,Google做到了全球多个数据中心,都是多活的。但是Google具体怎么做的,也没有多少人了解。另外一家就是Facebook,我们相对更了解一些,Facebook在做多个数据中心时,比如说美国和欧洲两个数据中心,确实都在支撑流量。但是欧洲的用户有可能需要访问美国的数据中心,当出现这种状况时,整个用户体验不是很好。

国内的情况,我们知道的像银行,还有其他一些行业,倾向于做异地灾备。银行一般都会有两地,一个地方是热点,另一个地方是冷备。当遇到故障时,就没有办法做出决定,到底要不要切到灾备数据中心,他们会碰到我们以前摸索时所面对的问题,就是不确定切换过程到底要多久,灾备中心到底多久才能把流量接管起来。而且接管以后,整个功能是不是都正常,也可能无法确定。

刚才也提到过,冷备的话,我们要备份全站,成本是非常高的。

如果每个地点都是活的,这些数据中心就可以实时承担流量,任何一点出问题,都可以直接切掉,由另外一点直接接管。相对冷备而言,这是一套可以运行的模式,而且风险非常低。

不过这样的话,平时要预留出很多流量才能保证?

毕玄:没错。因为在异地或同城建多个数据中心时,建设过程中一定都会保有一定的冗余量。因为要考虑其他数据中心出现故障时加以接管。不过随着数据中心建设的增多,这个成本是可以控制的。如果有两个异地的数据中心,冗余量可能是一倍,因为要接管全量。但是如果有三个数据中心,互为备份,就不需要冗余两倍了。

这个项目挑战还是比较大的。您可以介绍一下研发过程中遇到的挑战吗?又是怎样克服的?

毕玄:对于我们来讲,异地项目最大的挑战是延时。跨城市一定会有延时的问题。在中国范围内,延时可能在一百毫秒以内。

看起来单次好像没什么,但是像淘宝是个很大的分布式系统,一次页面的展现,背后的交互次数可能在一两百次。如果这一两百次全部是跨城市做的,整个响应时间会增加很多,所以延时带来的挑战非常大。

在解决挑战的过程中,我们会面临更细节的一些问题。怎样降低延时的影响,我们能想到的最简单、最好的办法,就是让操作全部在同一机房内完成,那就不存在延时的挑战了。所以最关键的问题,就是怎样让所有操作在一个机房内完成。这就是单元化。

为什么叫单元化,而没有叫其他名字呢?原因在于,要在异地部署我们的网站,首先要做一个决定。比如说,冷备是把整个站全部备过去,这样可以确保可以全部接管。但是多活的情况下,要考虑成本,所以不能部署全站。

整个淘宝的业务非常丰富,其实有很多非交易类型的应用,这些功能可能大家平时用的不算很多。但对我们来讲,又是不能缺失的。这部分流量可能相对很小。如果这些应用也全国到处部署,冗余量就太大了。所以我们需要在异地部署的是流量会爆发式增长的,流量很大的那部分。虽然有冗余,但是因为流量会爆发式增长,成本比较好平衡。异地部署,我们要在成本之间找到一个平衡点。所以我们决定在异地只部署跟买家交易相关的核心业务,确保一个买家在淘宝上浏览商品,一直到买完东西的全过程都可以完成。

其他一些功能就会缺失,所以我们在异地部署的并非全站,而是一组业务,这组业务就成为单元。比如说我们现在做的就是交易单元。

这时淘宝会面临一个比Google、Facebook等公司更大的一个挑战。像Facebook目前做的全球化数据中心,因为Facebook更多的是用户和用户之间发消息,属于社交领域。但淘宝是电商领域,对数据的一致性要求非常高,延时要求也非常高。

还有个更大的挑战,那就是淘宝的数据。如果要把用户操作封闭在一个单元内完成,最关键的是数据。跟冷备相比,异地多活最大的风险在于,它的数据会同时在多个地方写,冷备则不存在数据会写错的问题。如果多个地方在写同一行数据,那就没有办法判断哪条数据是正确的。在某个点,必须确保单行的数据在一个地方写,绝对不能在多个地方写。

为了做到这一点,必须确定数据的维度。如果数据只有一个维度,就像Facebook的数据,可以认为只有一个纬度,就是用户。但是像淘宝,如果要在淘宝上买一个东西,除了用户本身的信息以外,还会看到所有商品的数据、所有卖家的数据,面对的是买家、卖家和商品三个维度。这时就必须做出一个选择,到底用哪个维度作为我们唯一的一个封闭的维度。

单元化时,走向异地的就是买家的核心链路,所以我们选择了买家这个维度。但是这样自然会带来一个问题,因为我们有三个维度的数据,当操作卖家商品数据时,就无法封闭了,因为这时一定会出现需要集中到一个点去写的现象。

从我们的角度看,目前实现整个单元化项目最大的几个难点是:

第一个是路由的一致性。因为我们是按买家维度来切分数据的,就是数据会封闭在不同的单元里。这时就要确保,这个买家相关的数据在写的时候,一定是要写在那个单元里,而不能在另外一个单元,否则就会出现同一行数据在两个地方写的现象。所以这时一定要保证,一个用户进到淘宝,要通过一个路由规则来决定这个用户去哪里。这个用户进来以后,到了前端的一组Web页面,而Web页面背后还要访问很多后端服务,服务又要访问数据库,所以最关键的是要保障这个用户从进来一直到访问服务,到访问数据库,全链路的路由规则都是完全一致的。如果说某个用户本来应该进A城市的数据中心,但是却因为路由错误,进入了B城市,那看到的数据就是错的了。造成的结果,可能是用户看到的购买列表是空的,这是不能接受的。所以如何保障路由的一致性,非常关键。

第二个是挑战是数据的延时问题。因为是异地部署,我们需要同步卖家的数据、商品的数据。如果同步的延时太长,就会影响用户体验。我们能接受的范围是有限的,如果是10秒、30秒,用户就会感知到。比如说卖家改了一个价格,改了一个库存,而用户隔了很久才看到,这对买家和卖家都是伤害。所以我们能接受的延时必须要做到一秒内,即在全国的范围内,都必须做到一秒内把数据同步完。当时所有的开源方案,或者公开的方案,包括MySQL自己的主备等,其实都不可能做到一秒内,所以数据延时是我们当时面临的第二个挑战。

第三个挑战,在所有的异地项目中,虽然冷备成本很高,多活可以降低成本,但是为什么大家更喜欢冷备,而不喜欢多活呢?因为数据的正确性很难保证。数据在多点同时写的时候,一定不能写错。因为数据故障跟业务故障还不一样,跟应用层故障不一样。如果应用出故障了,可能就是用户不能访问。但是如果数据写错了,对用户来说,就彻底乱了。而且这个故障是无法恢复的,因为无法确定到底那里写的才是对的。所以在所有的异地多活项目中,最重要的是保障某个点写进去的数据一定是正确的。这是最大的挑战,也是我们在设计整个方案中的第一原则。业务这一层出故障我们都可以接受,但是不能接受数据故障。

还有一个挑战是数据的一致性。多个单元之间一定会有数据同步。一方面,每个单元都需要卖家的数据、商品的数据;另一方面,我们的单元不是全量业务,那一定会有业务需要这个单元,比如说买家在这个单元下了一笔定单,而其他业务有可能也是需要这笔数据,否则可能操作不了,所以需要同步该数据。所以怎样确保每个单元之间的商品、卖家的数据是一致的,然后买家数据中心和单元是一致的,这是非常关键的。

这几个挑战可能是整个异地多活项目中最复杂的。另外还有一点,淘宝目前还是一个高速发展的业务,在这样的过程中,去做一次比较纯技术的改造,怎样确保对业务的影响最小,也是一个挑战。

要将延时控制在1秒之内,网络和硬件方面都有哪些工作?

毕玄:如果网络带宽质量不好,1秒是不可能做到的。我们在每个城市的数据中心之间,会以一个点做成自己的骨干网,所以可以保障不同城市之间的网络质量。但是要保证到1秒,还必须自己再去做东西来实现数据的同步,这个很关键。这个东西现在也在阿里云上有开放了。

本文固定链接: http://www.chepoo.com/distributed-transaction-design.html | IT技术精华网

分布式交易设计:等您坐沙发呢!

发表评论