作者 臧秀涛
大数据时代,数据中心的异地容灾变得非常重要。在去年双十一之前,阿里巴巴上线了数据中心异地双活项目。InfoQ就该项目采访了阿里巴巴的林昊(花名毕玄)。
**InfoQ:首先请介绍一下数据中心异地多活这个项目。**
> **毕玄:**这个项目在我们内部的另外一个名字叫做单元化,双活是它的第二个阶段,多活是第三个阶段。所以我们把这个项目分成三年来实现。所谓异地多活,故名思义,就是在不同地点的数据中心起多个我们的交易,并且每个地点的那个交易都是用来支撑流量的。
**InfoQ:当时为什么要做这件事呢?**
> **毕玄:**其实我们大概在2009还是2010年左右的时候,就开始尝试在异地去做一个数据中心,把我们的业务放过去。更早之前,我们做过同城,就是在同一个城市建多个数据中心,应用部署在多个数据中心里面。同城的好处就是,如果同城的任何一个机房挂掉了,另外一个机房都可以接管。
> 做到这个以后,我们就在想,异地是不是也能做到这样?
> 整个业界传统的做法,异地是用来做一个冷备份的,等这边另外一个城市全部挂掉了,才会切过去。我们当时也是按照这个方式去尝试的,尝试了一年左右,我们觉得冷备的方向对我们来讲有两个问题:第一个问题是成本太高。我们需要备份全站,而整个阿里巴巴网站,包括淘宝、天猫、聚划算等等,所有加起来,是一个非常大的量,备份成本非常高。第二个问题是,冷备并不是一直在跑流量的,所以有个问题,一旦真的出问题了,未必敢切过去。因为不知道切过去到底能不能起来,而且整个冷备恢复起来要花多长时间,也不敢保证。因此在尝试之后,我们发现这个方向对我们而言并不好。
> 那为什么我们最后下定决心去做异地多活呢?
> 最关键的原因是,我们在2013年左右碰到了几个问题。首先,阿里巴巴的机房不仅仅给电商用,我们有电商,有物流,有云,有大数据,所有业务共用机房。随着各种业务规模的不断增长,单个城市可能很难容纳下我们,所以我们面临的问题是,一定需要去不同的城市建设我们的数据中心。其次是我们的伸缩规模的问题。整个淘宝的量,交易量不断攀升,每年的双十一大家都看到了,增长非常快。而我们的架构更多还是在2009年以前确定的一套架构,要不断的加机器,这套架构会面临风险。
> 如果能够做到异地部署,就可以把伸缩规模缩小。虽然原来就是一套巨大的分布式应用,但是其实可以认为是一个集群,然后不断的加机器。但是在这种情况下,随着不断加机器,最终在整个分布式体系中,一定会有一个点是会出现风险的,会再次到达瓶颈,那时就无法解决了。
> 这两个问题让我们下定决心去做异地多活这个项目。
> 为什么我们之前那么纠结呢?因为整个业界还没有可供参考的异地多活实现,这就意味着我们必须完全靠自己摸索。而且相对来讲,它的风险以及周期可能也是比较大的。
**InfoQ:这个项目具体是怎样部署的?**
> **毕玄:**以去年双十一为例,当时我们在杭州有一个数据中心,在另外一个城市还有个数据中心,一共是两个,分别承担50%用户的流量。就是有50%的用户会进入杭州,另外50%会进入到另外一个城市。当用户进入以后,比如说在淘宝上看商品,浏览商品,搜索、下单、放进购物车等等操作,还包括写数据库,就都是在所进入的那个数据中心中完成的,而不需要跨数据中心。
**InfoQ:这样的优势是?**
> **毕玄:**异地部署,从整个业界的做法上来讲,主要有几家公司,比如Google、Facebook,这两家是比较典型的,Google做到了全球多个数据中心,都是多活的。但是Google具体怎么做的,也没有多少人了解。另外一家就是Facebook,我们相对更了解一些,Facebook在做多个数据中心时,比如说美国和欧洲两个数据中心,确实都在支撑流量。但是欧洲的用户有可能需要访问美国的数据中心,当出现这种状况时,整个用户体验不是很好。
> 国内的情况,我们知道的像银行,还有其他一些行业,倾向于做异地灾备。银行一般都会有两地,一个地方是热点,另一个地方是冷备。当遇到故障时,就没有办法做出决定,到底要不要切到灾备数据中心,他们会碰到我们以前摸索时所面对的问题,就是不确定切换过程到底要多久,灾备中心到底多久才能把流量接管起来。而且接管以后,整个功能是不是都正常,也可能无法确定。
> 刚才也提到过,冷备的话,我们要备份全站,成本是非常高的。
> 如果每个地点都是活的,这些数据中心就可以实时承担流量,任何一点出问题,都可以直接切掉,由另外一点直接接管。相对冷备而言,这是一套可以运行的模式,而且风险非常低。
**InfoQ:不过这样的话,平时要预留出很多流量才能保证?**
> **毕玄:**没错。因为在异地或同城建多个数据中心时,建设过程中一定都会保有一定的冗余量。因为要考虑其他数据中心出现故障时加以接管。不过随着数据中心建设的增多,这个成本是可以控制的。如果有两个异地的数据中心,冗余量可能是一倍,因为要接管全量。但是如果有三个数据中心,互为备份,就不需要冗余两倍了。
**InfoQ:这个项目挑战还是比较大的。您可以介绍一下研发过程中遇到的挑战吗?又是怎样克服的?**
> **毕玄:**对于我们来讲,异地项目最大的挑战是延时。跨城市一定会有延时的问题。在中国范围内,延时可能在一百毫秒以内。
> 看起来单次好像没什么,但是像淘宝是个很大的分布式系统,一次页面的展现,背后的交互次数可能在一两百次。如果这一两百次全部是跨城市做的,整个响应时间会增加很多,所以延时带来的挑战非常大。
> 在解决挑战的过程中,我们会面临更细节的一些问题。怎样降低延时的影响,我们能想到的最简单、最好的办法,就是让操作全部在同一机房内完成,那就不存在延时的挑战了。所以最关键的问题,就是怎样让所有操作在一个机房内完成。这就是单元化。
> 为什么叫单元化,而没有叫其他名字呢?原因在于,要在异地部署我们的网站,首先要做一个决定。比如说,冷备是把整个站全部备过去,这样可以确保可以全部接管。但是多活的情况下,要考虑成本,所以不能部署全站。
> 整个淘宝的业务非常丰富,其实有很多非交易类型的应用,这些功能可能大家平时用的不算很多。但对我们来讲,又是不能缺失的。这部分流量可能相对很小。如果这些应用也全国到处部署,冗余量就太大了。所以我们需要在异地部署的是流量会爆发式增长的,流量很大的那部分。虽然有冗余,但是因为流量会爆发式增长,成本比较好平衡。异地部署,我们要在成本之间找到一个平衡点。所以我们决定在异地只部署跟买家交易相关的核心业务,确保一个买家在淘宝上浏览商品,一直到买完东西的全过程都可以完成。
> 其他一些功能就会缺失,所以我们在异地部署的并非全站,而是一组业务,这组业务就成为单元。比如说我们现在做的就是交易单元。
> 这时淘宝会面临一个比Google、Facebook等公司更大的一个挑战。像Facebook目前做的全球化数据中心,因为Facebook更多的是用户和用户之间发消息,属于社交领域。但淘宝是电商领域,对数据的一致性要求非常高,延时要求也非常高。
> 还有个更大的挑战,那就是淘宝的数据。如果要把用户操作封闭在一个单元内完成,最关键的是数据。跟冷备相比,异地多活最大的风险在于,它的数据会同时在多个地方写,冷备则不存在数据会写错的问题。如果多个地方在写同一行数据,那就没有办法判断哪条数据是正确的。在某个点,必须确保单行的数据在一个地方写,绝对不能在多个地方写。
> 为了做到这一点,必须确定数据的维度。如果数据只有一个维度,就像Facebook的数据,可以认为只有一个纬度,就是用户。但是像淘宝,如果要在淘宝上买一个东西,除了用户本身的信息以外,还会看到所有商品的数据、所有卖家的数据,面对的是买家、卖家和商品三个维度。这时就必须做出一个选择,到底用哪个维度作为我们唯一的一个封闭的维度。
> 单元化时,走向异地的就是买家的核心链路,所以我们选择了买家这个维度。但是这样自然会带来一个问题,因为我们有三个维度的数据,当操作卖家商品数据时,就无法封闭了,因为这时一定会出现需要集中到一个点去写的现象。
> 从我们的角度看,目前实现整个单元化项目最大的几个难点是:
> 第一个是路由的一致性。因为我们是按买家维度来切分数据的,就是数据会封闭在不同的单元里。这时就要确保,这个买家相关的数据在写的时候,一定是要写在那个单元里,而不能在另外一个单元,否则就会出现同一行数据在两个地方写的现象。所以这时一定要保证,一个用户进到淘宝,要通过一个路由规则来决定这个用户去哪里。这个用户进来以后,到了前端的一组Web页面,而Web页面背后还要访问很多后端服务,服务又要访问数据库,所以最关键的是要保障这个用户从进来一直到访问服务,到访问数据库,全链路的路由规则都是完全一致的。如果说某个用户本来应该进A城市的数据中心,但是却因为路由错误,进入了B城市,那看到的数据就是错的了。造成的结果,可能是用户看到的购买列表是空的,这是不能接受的。所以如何保障路由的一致性,非常关键。
> 第二个是挑战是数据的延时问题。因为是异地部署,我们需要同步卖家的数据、商品的数据。如果同步的延时太长,就会影响用户体验。我们能接受的范围是有限的,如果是10秒、30秒,用户就会感知到。比如说卖家改了一个价格,改了一个库存,而用户隔了很久才看到,这对买家和卖家都是伤害。所以我们能接受的延时必须要做到一秒内,即在全国的范围内,都必须做到一秒内把数据同步完。当时所有的开源方案,或者公开的方案,包括MySQL自己的主备等,其实都不可能做到一秒内,所以数据延时是我们当时面临的第二个挑战。
> 第三个挑战,在所有的异地项目中,虽然冷备成本很高,多活可以降低成本,但是为什么大家更喜欢冷备,而不喜欢多活呢?因为数据的正确性很难保证。数据在多点同时写的时候,一定不能写错。因为数据故障跟业务故障还不一样,跟应用层故障不一样。如果应用出故障了,可能就是用户不能访问。但是如果数据写错了,对用户来说,就彻底乱了。而且这个故障是无法恢复的,因为无法确定到底那里写的才是对的。所以在所有的异地多活项目中,最重要的是保障某个点写进去的数据一定是正确的。这是最大的挑战,也是我们在设计整个方案中的第一原则。业务这一层出故障我们都可以接受,但是不能接受数据故障。
> 还有一个挑战是数据的一致性。多个单元之间一定会有数据同步。一方面,每个单元都需要卖家的数据、商品的数据;另一方面,我们的单元不是全量业务,那一定会有业务需要这个单元,比如说买家在这个单元下了一笔定单,而其他业务有可能也是需要这笔数据,否则可能操作不了,所以需要同步该数据。所以怎样确保每个单元之间的商品、卖家的数据是一致的,然后买家数据中心和单元是一致的,这是非常关键的。
> 这几个挑战可能是整个异地多活项目中最复杂的。另外还有一点,淘宝目前还是一个高速发展的业务,在这样的过程中,去做一次比较纯技术的改造,怎样确保对业务的影响最小,也是一个挑战。
**InfoQ:要将延时控制在1秒之内,网络和硬件方面都有哪些工作?**
> **毕玄:**如果网络带宽质量不好,1秒是不可能做到的。我们在每个城市的数据中心之间,会以一个点做成自己的骨干网,所以可以保障不同城市之间的网络质量。但是要保证到1秒,还必须自己再去做东西来实现数据的同步,这个很关键。这个东西现在也在阿里云上有开放了。
**InfoQ:异地多活其实也是实现高可用。阿里技术保障的[梁耀斌(花名追源)](http://2015.qconbeijing.com/speakers/201795)老师会在4月23日~25日的[QCon北京2015大会](http://2015.qconbeijing.com/)上分享《你的网站是高可用的吗?》,因为当时的题目和内容也是您参与拟定的。您可以先谈一下其中的一些标准吗?**
> **毕玄:**其实每家比较大的互联网公司,每年可能都会对外公开说,我们今年的可用性做到了多少,比如4个9或者5个9。但是每家公司对可用性的定义可能并不一样。比如说,有的公司可能认为业务响应时间超过多少才叫可用性损失,而其他公司可能认为业务受损多少就是可用性损失。
> 我们希望大家以后有一个统一的定义,这样就比较好比较了。我们发现,真正所有做到高可用的网站,最重要的一点是故障恢复时间的控制。因为出故障是不可避免的,整个网站一定会出现各种各样的故障,关键是在故障出现以后,应对能力有多强,恢复时间可以做到多短。追源会在QCon上分享,我们在应对不同类型的故障时,我们是怎样去恢复的,恢复时间能控制到多短,为什么能控制到那么短。在不同的技术能力,以及不同的技术设施的情况下,能做到的恢复时间可能是不一样的,所以我们会定义一个在不同的技术能力和不同的技术设施的情况下,恢复时间的标准。如果恢复时间能控制得非常好,可能整个故障控制力就非常强。举个例子,比如淘宝因为能够做到异地多活,并且流量是可以随时切换的,所以对于我们来讲,如果一地出现故障,不管是什么原因,最容易的解决方案,就是把这一地的流量全部切走。这样可以把故障控制在一分钟以内,整个可用性是非常高的。
> 关于系统的容灾能力,国家也有一个标准,最重要的一点就是故障的恢复时间。如果大家都以故障恢复时间控制到哪个级别来衡量,那所有网站就有了一套标准。
**InfoQ:好的,异地多活我们就聊到这里。您现在在维护一个叫做HelloJava的微信公共帐号,您在工作中还是会去调优一些具体的Java问题吗?**
> **毕玄:**没错。我在阿里巴巴这些年来,很多问题有一些会流转到我这里,或者有人会反馈到我这里,所以我会介入到很多问题的排查,现在也是一样,有些问题我可能就会介入,直接去排查。为什么有HelloJava那个微信公共账号呢?最大的原因也是因为,我们都知道很多人会排查故障,有些人可能只是一眼扫过去就已经知道原因是什么。为什么呢?他可能已经排查过很多的故障,积累出了经验,并不一定是这个人的能力比你强,可能就是因为他见的比你多,他对工具使用的熟悉程度比你强。比如说我们看到故障很多,排查故障很厉害的人,他可能就是会善于用各种各样的工具,而且用的非常熟练。所以我做自己的HelloJava,就是希望有更多的人看到,我们在面对一个故障的时候是怎样处理的。希望大家即使没有处理过这个故障,至少也看过一篇文章,也许在下次面对这个故障时,至少有点思路,知道应该怎么去处理。这个也是阿里巴巴分享给外面的一些经验,很多时候就是经验的积累。
**InfoQ:您最近在HelloJava里提到了一些期待的Java特性,您这边会将它们反馈给Oracle,让他们加入吗?**
> **毕玄:**我们跟Oracle官方有过一些交流,谈到我们期望的JVM的一些改进。但是说实话,因为我们看到的很多JVM的问题,可能是因为我们流量比较大,我们对Java的性能、高并发有很高的期望。如果能够突破一点,对于我们整个网站来讲,提升可能就是巨大的。但是对于Oracle来讲,因为OpenJDK不仅仅是为大公司做的,而是为所有不同的用户,比如中小企业、大用户,所以他们必须衡量需求的分布。所以有可能我们的需求,对于Orcale的官方JVM团队而言,只是小众需求,他们不大会投入很大精力去做。
**InfoQ:所以您这边的团队会做一些定制?**
> **毕玄:**对。很多人知道,赵海平加入了我们的团队,如果知道他背景的话,知道他以前做过PHP运行引擎的开放,不仅仅是HipHop的翻译,还包括怎么运行整个PHP应用程序。其实你可以认为也会类似VM,因为我们已经看到在Java、JVM的哪些点上如果有突破,可以给我们带来巨大提升,所以既然官方很难往前推进,那我们就自己来推进。
### 受访者介绍
**林昊(花名毕玄)**于06年加入淘宝,为阿里巴巴集团核心系统资深技术专家。目前是阿里巴巴技术保障部的研究员,负责性能容量架构。