2015 年 11 月 12 日 ,又拍云架构运维大会上海站在沪举行,途牛运维总监谭俊青在会上作题为《浅谈架构升级》的分享,以下是演讲实录:
大家早上好,我今天要分享的,是跨数据中心状态同步两地三中心的理论技术。先简单自我介绍一下,我实际上是出身数据库的,今天讲的课题和数据库或多或少有一些关系。
大家之前参加过不少的分享会。很多人在分享的时候,主要是通过 PPT做各种技术点的分析,内容看起来比较丰富、耀眼。这些东西最多告诉你“怎么做”,但很少交代“为什么这么做?”。
这是因为很多人经过多年沉淀,在各个知识点都有很多的积累,形成了知识丛林。你可以看到他在某个点的产出,但很难还原当初这么做的原因。我今天跟大家分享的,就是一个可以让大家理解“我为什么要这么去做”的知识点,希望可以成为大家头脑中的参考,或者给大家一些启发。
分布式协议/概念
开始之前,我先介绍一下分布式的协议。今年的双十一阿里的创造了交易额是很惊人的,但阿里的技术团队出来做技术分享时,他们提到一点,就是支付宝交易每秒钟到了 8.5 万笔,这里面有很多东西可以分析出来。
其中的分布式协议,全球范围内真正能够实现分布式一致性算法,只有两个,一个是 paxos,一个是 raft,paxos 有很长的历史,早期是谷歌实现的,后来论文发布之后,中间有一个组建也是用 paxos 的 算法,在这里面 paxos 实现包括谷歌公开的技术。2012年,有两位教授发表了一篇论文,叫做 raft,非常值得去学习。还有一个是 2pc,也可以实现分布式同步,但是它中间可能会出现问题,我们一般要真正实现分布式数据状态协议的话,一般会选择 paxos 和 raft。从容易实现的角度考虑的话,就采用 raft。
远距离跨机房同步问题
首先介绍一下做这个事情的背景和出发点。以途牛为背景,途牛开始他们的系统都是在南京这一块,但为了照顾到用户体验,我们就把网站迁到北京。怎么做呢?我们进行了调用,这里面存在很多问题。包括远距离跨机房同步问题,以及专线稳定性对服务质量的影响。我们一般系统网络都是 4 个 9 或以上,还有宽带挤占,各个系统调用等。而我要讲的是数据库同步延时。
我们后台系统允许客户注册,在网站上注册可以选择南京或北京,我们选择南京,因为更多是南京在用。注册的时候到北京去,我们读的是的北京数据库。但如果出现延时,就无法登录,这样用户体验是非常糟糕的。此外就是不能做强一致性高可用。如果在两地做,可能有同步有做法,万一出问题需要切换,数据可能会丢失。这点大家应该都有了解。
CAP 中,我们的选择
关于 CAP,很多人都了解它的特点,就是一致性,可用性,分区容错性。但这三者不可兼得,然而分区(P)是必然的。我们选择什么呢?对电商来说,它对数据的要求比较高,所以我们选择 consistency(一致性)。
大家可以注意到图片中间是一个小三角,说明这个数据很难落地。看上去 CAP 能够满足了,而实际情况不是这样的。如果大家深入了解的话会清楚。
刚才说过,我们的选择针对当前的这种开源,或者是技术实现。我们现在用开源数据库,实现主从复制、用来做高可用;不能丢失数据;只能牺牲一定的性能,等待数据被同步。但远距离机房延时太大,从而影响了系统吞吐量,所以我们做了机房搬迁。今年我们做了比较大的动作:把北京整个机房搬到南京来,因为我们整个系统还是放在南京的。
数据的传输
这个图大家应该见过,我们的应用是先向数据库发起事务,这个事务完成后,它会写到我们的 log 里面,然后返回应用。这个过程看起来比较复杂,但有一个缺陷,我这里就先不讲了,大家有兴趣可以来交流。
这种专线最终落地是什么?就是光纤传输。我们算一下它的传输性能:真空中光速 30 万千米/S,光纤材质折射率 1.45 左右,全反射传输,路径大于光纤长度,折算下来小于 20 KM/0.1MS,如果算同城的话,是1000ms / 0.2ms=5000(TPS)。我们可以通过技术提升这个速度,这与业务具体架构相关。
我们再看一下南北之间的架构。南京到北京,具体距离不了解,而且我相信光纤不是直线布置,中间会经过很多的弯和网络设备。南北传输,可以达到 1000MS / 50MS=20(TPS)。
基于 HA 的数据中心系统构建
之前我们会员系统,后台系统做的并不完善。我们可能被用户刷会员,甚至可能被刷坏。当时我们支持的事务量很小。这其实跟各个创业公司有点类似,在高速发展阶段,整体的速度没有那么快,为了降低成本,可能会让一个功能快速上线,但中间如何优化、如何实现都没有考虑过。这样的系统,经过多年累积,当时里面就出现了一些问题。比如说要求手机号码,为了保持全局一致性,一个用户注册之后,把后面所有的都堵塞掉了。后面,我们就用了异步的方式解决了这个问题。
双十一阿里做到了 8 万 5 千笔/秒的交易频率,他们是怎么做到的?最早从腾讯开始,他们通过 QQ 号取模的方式,道理其实是一样的。一个整体,如果是串行,他的分布量是比较有限的。刚才说的 0.2 毫秒,理论上只能达到 5 千每秒,如何去提升呢?在编程上面要作调整。当系统发展到一定规模后,我们要提升整个系统吞吐量,就必须考虑低层的架构,哪怕谷歌也是一样。曾经谷歌发现这里面数据库使用越来越多,各种不可用性,他们就把系统迁移到自己开发,这么大的数据量怎么去做?如下图中所述。
HA 组建及双中心 HA 缺陷。这里面有 heartbeat,keepalived,etc,也是一样的,但是缺少第三方仲裁,会导致脑裂,特别在偶数的下面。如果两部分都正常,可能会引起数据不一致,进而造成数据丢失等。我们一般选择F= 1,或者是 2,就是 5 个节点,我们使用比较成熟的解决方案。我了解到有很多是 5 节点的方案,进一步提高了可能性,允许两个节点失效。刚才讲到同城机房距离最好在 10 公里,当时美国是要求 30 公里,经我们了解,这并不是完全合理的。
三中心 HA。刚才说了两中心缺少仲裁,因此我们选择三中心,三中心有仲裁,三个节点,至少不会发生脑裂的现象。我们选择了同城加上异地,这比较容易理解:同城可以保证一定的吞吐量。同城数据中心降低的同步延时,低延时极大提升了吞吐量,第三数据中心参与选择仲裁及灾备恢复。为了安全,第三中心一般距离会比较远。比如我们南京的机房会远一点,就是为了避免出现地震等自然灾害同时影响三个中心的情况发生。
刚提到的吞吐量提升,还是可以采用各种各样的方法实现的。阿里双十一的峰值可以达到 8 万 5 千笔/秒的交易。他们引以为傲的,是去年只有 10% 的交易在 Oceanbase,今年在 100% 都迁到 Cceanbase。这是怎么实现的?Sharding 分区是避免不了的。采用发号器发号避免冲突,实现高并发,分区间用 2PC 实现分布式事务。这里面还涉及到全局,还有部分采用队列异步处理。做全局索引对业务影响并不大,因此一般统计的时候,往往通过异步去实现。
最后总结一下。两地三中心,当中 2 个中心一定是同城,因为要保证它的吞吐量、保证业务可用性。三中心对应状态同步的三节点,两地是照顾到安全和性能。我可能把第三个机房放到异地比较远的距离去做。