小蚂蚁说:
关于蚂蚁金服自研的金融级分布式关系型数据库 OceanBase 的故事相信大家已经不再陌生了。其中 OceanBase 的大规模金融级的高可用及容灾能力深入人心,那么它究竟是怎么做到的呢?
本文用较为详尽的篇幅分别为大家总结和回顾了传统数据库产品常用的高可用及容灾方案,并以此为基础深度解读了基于 OceanBase 最佳实践的分布式数据库的高可用及容灾方案。一起来学习一下吧~!
众所周知,作为生产系统中极为关键的核心软件,数据库产品的高可用性一直是使用者极为关注的功能点。尤其是在金融这样一个特殊的领域里,无论是从监管的要求来看,还是从业务需求本身来看,都需要提供 24*7 持续不间断的服务,这就对金融行业中数据库产品的高可用性提出了很高的要求,不但需要应对个别硬件故障的情况,还必须能够应对机房整体故障和城市灾难等极端情况,保证数据库在各种意外情况下都能持续提供服务,即具备机房级容灾能力和城市级容灾能力。
本文的主要目的,是总结和回顾一下传统数据库产品常用的高可用及容灾方案,并向读者介绍一下以 OceanBase 为代表的分布式数据库常用的方案,希望能够起到抛砖引玉的作用,引发读者关于新型分布式架构下高可用及容灾方案的思考。
传统商业数据库的高可用方案
首先,我们回顾一下传统的关系型数据库产品(如 Oracle、DB2 等)常用的高可用及容灾技术。我们知道,传统数据库产品最初都是单点架构,并不具备高可用设计,更多的是基于高端硬件产品满足“硬件可靠”的假设。随着时间的推移,传统数据库产品先后推出了采用“主从复制”架构的高可用方案,比如 Oracle 的 Data Guard 技术和 DB2 的 HADR 技术,其主要思路是:在原有的单数据库节点(主节点)之外再增加一个对等的数据库节点(从节点),通过数据库层面的复制技术(通常是日志复制)将主节点产生的数据实时复制到从节点;正常情况下从节点不提供对外服务,当主节点发生故障时,在从节点上执行“切主”动作将从节点变成主节点,继续提供服务。
在主从节点的部署方式上,除了本地单机房部署外,往往也支持同城灾备部署和异地灾备部署,因此也就具备了机房级容灾和城市级容灾的能力。很多新兴的数据库产品(如 MySQL)也是采用“主从复制”模式来实现高可用及容灾特性。
除了数据库层面的主从复制技术之外,还有一些在底层硬件上实现的高可用方案,比如在主机层面用 HACMP 技术以应对主机故障,或者在存储层面采取复制技术(比如 FlashCopy)来提供数据冗余等。这些技术虽然也可以用来实现高可用和容灾能力,但和应用的整合度不高,会使灾难切换方案变得很复杂,并且会有相对较长的故障恢复时间(RTO),所以通常不是数据库用户的首选。
最后,近些年还出现了一些支持异种数据库之间相互复制数据的产品,比如 IBM CDC 和 Oracle Golden Gate(OGG)。这些产品的特点是比较灵活,可以支持异种数据库之间的数据复制,也可以指定只复制数据库中的部分对象(比如只复制指定几张数据表的数据)。但这些产品的缺点也很明显:首先相对于数据库主从复制来说时延偏大,通常会达到秒级以上,而且往往做不到数据库层面 100%的完全复制。因此,这种方式通常作为不同数据库产品之间做数据“准”实时同步的手段,而不会作为数据库产品实现高可用及容灾的手段。
稍微总结一下,传统的数据库产品通常会采用下面的方法实现高可用:
在主机层面实施高可用(HACMP)架构,以应对主机故障所带来的影响(非首选方案)。
*在存储层面采用数据复制技术(比如 FlashCopy)来提供数据冗余,以应对存储损坏所带来的影响(非首选方案)。
在数据库层面提供“主从复制”技术(首选方案)。
第三方数据复制产品,如 CDC、OGG 等(很少采用)。
通过上述的各种技术,尤其是数据库“主从复制”技术,使得意外发生时数据库可以在一定时间内恢复服务,并且大部分数据不会丢失,具备了一定的高可用及容灾能力。但是,上面这些技术也有一些难以克服的缺点,以“主从复制”技术为例,虽然它是传统数据库里最先进也是最常用的高可用及容灾技术,但还是有一些无法解决的问题:
通常情况下无法做到 RPO=0,即主节点发生故障或者灾难时有交易数据的损失。
可能有的读者会说:你说错了!主从复制技术也能实现 RPO=0。
是的,理论上讲主从复制技术是可以利用强同步模式(比如 Oracle Data Guard 中采用 Max Protection 模式,或者 DB2 HADR 中采用 Sync 模式)做到 RPO=0,但实际应用中,像银行核心系统这样的关键业务里却不会采用。为什么呢?因为这种模式将主节点和从节点以及主从节点之间的网络环境紧紧地绑在了一起,主节点的稳定性将不再由它自己决定,而要同时看从节点和网络环境的脸色:一旦从节点或者网络环境稍微抖动一下,主节点的性能就会受到直接影响。如果主节点和从节点之间是跨机房甚至跨城市部署,发生这种问题的概率会更大,影响也会变得更加显著。从某种程度上讲,和单节点模式相比,这种模式下主节点的稳定性不但没有增加,反而是降低了。如果有银行的朋友在关键业务中应用过 Oracle Data Guard 或者 DB2 HADR,对强同步模式所带来的问题应该是深有体会的。
RTO 相对较大,通常以十分钟甚至小时为计算单位,会给业务带来比较大的损失。
造成这一情况的根本原因,是“主从复制”模式下从节点不具备自动切主的能力。
由于“主从复制“模式中缺少第三方仲裁者的角色,当主从节点之间的心跳信号异常时,从节点无法靠自己判断到底是主点故障了,还是主从之间的网络故障了。此时,如果从节点认为是主节点故障而将自己自动切换成主节点,就极容易导致“双主”、“脑裂”(brain-split)的局面,对用户来说这是绝对无法接受的结果。所以数据库“主从复制”技术从来不会提供“从节点自动切换为主节点”的功能,一定要由“人”来确认主节点确实故障了,并手工发起从节点的切主动作,这就大大增加了系统恢复的时间(RTO)。
聊完了传统数据库的高可用技术,我们再来看看另一种逐渐被越来越多的技术厂商所采用的技术,那就是分布式多副本数据一致性技术,通常是基于 Paxos 协议或者 Raft 协议来实现。这种技术会将数据保存在多份副本上,每一次对数据的修改操作都会强同步到多数派副本上,在保证了数据冗余的同时,不再像“主从复制”技术那样依赖某个数据节点的稳定性,从而消除了传统主从复制技术下从节点给主节点带来的风险。同时,在主节点故障的情况下,其余节点会自动选举出新的主节点以实现高可用(个别从节点故障则完全不影响服务),整个过程非常快速且完全无需人工干预。因此,这种技术不仅能保证 RPO=0,而且大大减小了 RTO,相比传统“主从复制”技术来说可以提供更强大的高可用能力。
此外,为了抵御机房级灾难和城市级灾难,可以将多份副本分散部署在多个机房里甚至多个城市中,以避免机房级灾难或者城市级灾难损毁多数派副本。这样就具备了机房级容灾和城市级容灾的能力,进一步加强了高可用的能力。
OceanBase 常用的高可用及容灾方案
OceanBase 数据库从诞生之初,就利用 Paxos 协议在底层实现了多副本数据一致性,具有上述“RPO=0、低 RTO(通常在 30s 以下)、故障时自动切换”的优势。而经过多年实际应用场景的历练后,尤其是像支付宝、淘宝、网商银行这种高并发、高访问量、24*7 持续交易场景的磨练,OceanBase 数据库已经摸索出一套完整的、经过实践检验的高可用及容灾方案。下面我们就结合 OceanBase 数据库的实践经验,向大家介绍一下分布式数据常用的一些高可用及容灾方案。
特别说明一下,在后文的示意图中会有一些经常用到的名词,在此先做个简单的说明,以方便大家理解:
OBServer
一个 OBServer 指的是一个独立提供服务(share-nothing)的 OceanBase 数据库节点,这是一个软件层面的定义。但通常一台物理服务器上只有一个 OBServer,因此也可以认为一个 OBServer 等同于 OceanBase 数据库集群的一个物理节点。
Zone
这是 OceanBase 数据库的一个内部概念。一个 Zone 是一个或者一些 OBServer 组成的逻辑集合,一个 Zone 里的所有 OBServer 都在一个机房内。
从分布式多副本数据一致性协议的角度来看,可以认为一个 Zone 就是 OceanBase 数据库集群的一个“副本”,如果是三副本架构那就会有三个 Zone。
IDC
IDC 就是大家通常理解的“机房”的概念,一个 IDC 就代表一个机房。
1.1 单机房 3 副本
这是最简单的一种方案,在一个机房内找足够多的机器,把它们划分成 3 个 Zone,每个 Zone 里一份副本。
这种方案具备一定程度的高可用能力,可抵御个别硬件故障,比如在个别服务器宕机、个别硬盘损坏等情况下,数据库集群还能持续提供服务。此外,这种方案具有部署方便,成本低的特点,只要有一个机房,机房内有足够多的联网机器,就可以部署了。
但这种方案也有一个非常明显的劣势:不具备容灾能力。如果发生机房级灾难或者城市级灾难,首先会导致交易停止,而极端情况下(比如机房所有机器损毁)甚至会导致数据丢失。
综合来看,这种方案虽然部署方便,也具备高可用特性,但其容灾的能力却是最低的,对于具有容灾要求的系统来说显然是不适合的。如果用户的硬件条件有限,只能提供一个机房,并且用户对系统的容灾能力没有要求,那么这种方案是一个非常合适的选择。
1.2 同城 3 机房 3 副本
同样是一个城市内部署 3 副本,这种方案相对于“单机房 3 副本”来说就更进了一步:在同一城市内找 3 个不同的机房,每个机房内部署 1 个 Zone(1 份副本),形成一个跨机房部署的数据库集群。
由于分布式多副本数据一致性协议要将每一个事务的数据强同步到多数派副本中,这种部署模式下必然导致频繁的跨机房同步操作。为了保证数据库的写性能,对机房之间的网络质量有比较高的要求,通常要求任何两个机房之间的网络时延不超过 2 毫秒(ms)。(P.S. 后面所有关于“同城机房”的描述中,默认都有类似的网络要求,后文就不再赘述了)
相对于“单机房 3 副本”来说,这种方案的优势是很明显的:除了可以抵御个别硬件故障,还可以抵御机房级灾难:任何一个机房遇到灾难,都不会导致交易停止或者数据丢失。
不过,并不是每一个用户都能够提供“同城三机房”的部署条件。即使是高端企业级用户,往往也只具备同城 2 机房(主机房+同城灾备机房)的条件,因此 3 机房对用户的基础设施来说提出了一定的挑战,也增加了用户的部署成本。如果考虑到上面说的任意 2 个机房之间都要做到“网络低延时”,那成本会进一步增加。因此,在考虑这种部署方案时,要事先和用户做好充分的沟通,确保用户能提供符合要求的基础设施。最后还要指出的一点就是,这种方案仍然不具备城市级容灾的能力,如果发生城市级灾难,还是会导致交易停止,甚至有数据丢失的风险。
综合来看,如果用户能够提供同城 3 机房的硬件设施,并且没有城市级容灾的要求,那么推荐使用这种方案,可以在城市内提供非常好的高可用及容灾能力。事实上,OceanBase 数据库的一些外部企业级客户就是采用了这种部署方式,收到了很好的效果。
如果用户暂时只具备同城 2 机房的条件,那么可以考虑在城市内租借一个机房以满足“同城 3 机房”的条件,其成本相对于建设一个全新 IDC 来说还是低了很多。甚至可以只为个别数据库集群租借一个同城机房内的部分机柜,这样就进一步降低了成本,对企业级用户来说这个成本应该还是在可接受范围内的。
1.3 3 地 3 机房 5 副本
前面介绍的几种方案中,提到了机房内高可用能力和机房级容灾能力,但是都无法抵御城市级灾难。下面向大家介绍一种具备城市级容灾能力的方案:3 地 3 机房 5 副本方案。
这种方案相对来说要复杂一些。首先需要有 3 个城市,每个城市各有 1 个机房,利用这 3 个机房组成一个跨机房部署的 OB 集群。其次,和前面“同城 3 机房 3 副本”的方案类似,这种方案对不同机房间的网络质量是有一定要求的,通常来说需要满足下面的条件:
1)有 2 个城市的距离相对较近(比如杭州和上海),它们之间的网络时延低于 10 毫秒(ms)。这 2 个城市的机房中各部署 2 个 Zone(副本)。
2)第 3 个城市和前两个城市的距离相对较远(比如深圳),它和前 2 个城市之间的网络时延应保证在 30 毫秒(ms)内。这个城市的机房内部署 1 个 Zone(副本)。
在这种部署模式中,距离较近的 2 个城市有 2 个 IDC,合计 4 份副本,构成了 Paxos 协议要求的多数派,因此日常写交易中的强同步操作会集中在这 2 个城市中,不会涉及到距离较远的第 3 个城市,有效避免了远距离 RPC 对交易性能带来的影响。如果 2 个距离较近的城市中有任何一个 Zone 发生故障,剩下的 3 个 Zone 依旧构成多数派,还是不会涉及到距离较远的第 3 个城市,性能不会受到影响。如果这 2 个城市中有 1 个城市发生了机房级灾难或者城市级灾难,剩下的 1 个城市和距离较远的第 3 个城市合在一起还有 3 个 Zone,依旧构成多数派,还是可以继续提供服务,但此时远距离 RPC 操作将不可避免,性能也会因此而受到影响。因此,这种方案可以全方位抵御个别硬件故障、机房级灾难和城市级灾难,提供最高级别的高可用性,使数据安全性得到了最大程度的保障。
不过,这种方案虽然能够提供全面的数据安全性保护,在实际部署中也会面临一些问题和挑战。首先,需要在 3 个城市内各有一个机房,3 个城市之间要满足“2 近 1 远”,而且相互之间的网络时延也要满足一定条件(详见前文描述),可以说这对用户的基础设施条件提出了非常大的挑战,即使对高端企业级用户来说,也很难满足这个条件,最多只具备 2 地 3 机房的条件。另外,5 副本相对于 3 副本来说增加了 2 个副本,进一步提高了硬件成本,也加大了这个方案的难度。
在实际应用中,如果用户对 SLA 提出了最高要求,需要抵御机房级灾难和城市级灾难,并且希望做到“RPO=0、低 RTO、故障时自动切换”,那么此方案将是不二之选。事实上,网商银行的数据库集群部署就是采用这种架构,支付宝中的部分核心数据也是采用了这种架构,它们为业务提供了最佳的数据安全性保障。
对国内的企业级用户来说,在短期内恐怕还很难满足这种方案的基础设施要求。但目前只有 3 城市的部署架构才能在城市级灾难时做到“RPO=0、低 RTO、故障时自动切换”,因此从长远考虑可以在基础设施层面提前有所规划。
1.4 同城 2 机房 3 副本
前面介绍过,如果只需满足机房级容灾的要求,那么可以考虑“同城 3 机房 3 副本”的方案,以抵御个别硬件故障和机房级灾难。但由于历史原因,很多企业用户都建设了“同城 2 机房(主机房+同城灾备机房)”的基础设施,却很少有用户具备“同城 3 机房”的条件。此时虽然可以租用一个同城机房来满足 3 机房条件,但如果用户真的找不到合适的第 3 机房,是否就不能在 2 机房中部署 OceanBase 数据库集群了呢?
其实,这种情况下还是可以利用 2 机房来完成部署的,只要在主机房中部署 2 个 Zone,同城灾备机房中部署 1 个 Zone,就构成了一个跨机房部署的数据库集群。
这种部署模式下,主机房内的 2 个 Zone 构成了多数派,因此日常的写交易都会在主机房内部完成数据强同步,可以保证最佳性能。同时,这种方案也可抵抗个别硬件故障,如个别服务器宕机、个别硬盘损坏等情况。
但如果主机房发生机房级灾难,那么整个数据库集群只剩下同城灾备机房的 1 个 Zone,不再满足多数派条件,无法继续提供服务。因此这种方案是不能抵御机房级灾难的,只是在同城灾备机房中保留了一份数据,以后可以将数据恢复出来(但 RPO>0,数据会有少量丢失),避免了数据全部丢失的情况。
综合来看,“同城 2 机房”的条件下,如果拥有多数派副本的机房(通常是主机房)发生灾难,剩下的一个机房无法单独提供服务(这是由分布式多副本数据一致性协议的理论所决定的)。从高可用的角度来看,这种方案不具备机房级容灾的能力,只是避免了数据全部丢失的风险,这个结果大大降低了同城灾备机房的实际意义。
在实际应用中,OceanBase 数据库基本不会采用这种方案。相比之下,“同城 3 机房 3 副本”方案具备提供机房级容灾的能力,能提供更强的高可用性,是一个更好的选择。考虑到增加第 3 个机房为用户带来的额外成本,OceanBase 数据库还提供了“日志副本”技术:用户可以在已有的 2 个机房中各部署 1 个普通副本,在第 3 个(新增加的)机房中部署 1 个日志副本。相对于普通副本来说,日志副本可以显著降低存储成本,这样可以在完全不影响 RPO 的情况下降低第 3 个机房的拥有成本,减小了用户部署第 3 个机房的难度。
1.5 2 地 3 机房 5 副本
前面介绍过,“3 地 3 机房 5 副本”的方案可以提供最高级别的高可用性,可以抵御个别硬件故障、机房级灾难和城市级灾难等各种情况。但我们同时也提到了,传统企业用户很少能满足“3 地 3 机房”的要求,很多企业用户只具备 “2 地 3 机房(主机房+同城灾备机房+异地灾备机房)”的条件。那么这种情况下,分布式数据库是否能利用“2 地 3 机房”完成部署呢?
事实上,这种情况下 OceanBase 也可以完成数据库集群的部署,只要在主机房和同城灾备机房中各部署 2 个 Zone,在异地灾备机房中部署 1 个 Zone,就构成了一个跨机房部署的数据库集群。
从架构上看,这种部署方案和“3 地 3 机房 5 副本”方案有类似之处,可以抵御个别硬件故障和机房级灾难(读者可参照前面“3 地 3 机房 5 副本”方案的描述做推理,具体过程这里就不详述了)。
但是和“3 地 3 机房 5 副本”相比,这种方案缺少了城市级容灾的能力:一旦主机房和同城灾备机房所在的城市发生灾难,剩下的异地灾备机房只有 1 个 Zone,不再满足多数派条件,无法继续提供服务,只是在异地灾备机房中保留了一份数据,以后可以将数据恢复出来(但 RPO>0,数据会有少量丢失),避免了数据全部丢失的情况。
综合来看,“2 地 3 机房”的条件下,如果拥有主机房和同城灾备机房的城市发生灾难,剩下的一个城市无法单独提供服务。从高可用的角度来看,这种方案不具备城市级容灾的能力,只是避免了数据全部丢失的风险,这个结果大大降低了异地灾备机房的实际意义。
在实际应用中,OceanBase 数据库基本不会采用这种方案。相比之下,“3 地 3 机房 5 副本”方案具备城市级容灾的能力,能提供更强的高可用性,是一个更好的选择。此外,还可以进一步利用前文提到的“日志副本”技术:用户可以在已有的 2 个城市中各部署 2 个普通副本,在第 3 个(新增加的)城市中部署 1 个日志副本,这样可以在完全不影响 RPO 的情况下降低第 3 个城市中机房的拥有成本,减小了用户在第 3 个城市中部署机房的难度。
最后,如果用户实在无法找到第 3 个城市来部署机房,但同时可以接受“发生城市级灾难时 RPO>0”的代价,那么可以在两个城市之间采取“集群间数据复制”的方法(后文有详细的介绍)。这种方式的弊端很明显,遇到城市级灾难时会有“RPO>0,不能自动切主导致 RTO 较长”的问题,但它可以利用 2 个城市实现城市级(有损)容灾,减小了部署的难度。如果采用此方案的话,“主”城市应该采用“同城 3 机房 3 副本”的架构,以提供机房级容灾的能力。
1.6 集群间数据复制
这种方案类似传统数据库的“主从复制”方案,通过数据复制软件将一个 OceanBase 数据库集群的数据复制到另一个(或者多个)OceanBase 数据库集群,以应对单个 OceanBase 数据库集群的故障。通常来说,不同的 OceanBase 数据库集群会部署在不同的 IDC 中,以应对机房级灾难和城市级灾难。
这种方式主要是为了应对以下几种情况:
只有 2 个机房的条件下,希望能够具备机房级容灾的能力。
只有 2 个城市有机房的条件下,希望能够具备城市级容灾的能力。
此时,分布式多副本数据一致性协议便无法满足需求,比如前面提到过的:“同城 2 机房 3 副本”的方案无法抵御机房级灾难,“2 地 3 机房 5 副本”的方案无法抵御城市级灾难。而采用传统数据库的“主从复制”模式(准确地说,是它的一个变种),则能满足这类需求。
不过,这种方案的弊端也是很明显的。首先,和传统数据库一样,具有“RPO>0,不能自动切主导致 RTO 较长”的问题,其次这种部署方式下数据的副本数达到了 6 个,成本也比较高。
综合来看,这种模式只适用在“用户实在无法满足机房配置要求,但又希望具备机房级容灾和城市级容灾能力”的特殊场景下。我们前面提到过,由于历史原因,不少企业级用户恰恰是有这种需求:希望用同城 2 机房的部署实现机房级容灾能力,用 2 地 3 机房的部署实现城市级容灾能力。因此,如果用户能接受此方案的各种弊端(RPO>0,RTO 较长,副本数过多),就可以用这种方案实现高可用及(有损)容灾能力。
总结
通过前面对几种方案的详细阐述,相信大家已经对 OceanBase 及分布式数据库的高可用和容灾方案有了大致的了解。说来说去,核心思想就是要充分利用分布式多副本数据一致性协议的原理,并结合各种意外情况的具体特点(个别硬件故障?机房级灾难?还是城市级灾难?),找到对应的解决之道。如果客户的基础设施条件有限,不能满足分布式多副本数据一致性协议的部署要求,那么可以考虑引入其它方式,比如集群间数据复制。
下面的表格中,将上面几种方案做了一个总结,方便读者参考:
大体来讲,针对不同的具体情况,下面几种方案都满足了“RPO=0、低 RTO、故障时自动切换”的要求,而且在技术上没有明显的缺陷,应该作为高可用及容灾方案的首选:
单机房 3 副本方案
如果没有任何机房级容灾或者城市级容灾的要求,只有最简单的高可用要求,那么这种简单易行的部署方案是再好不过了。
同城 3 机房 3 副本方案
如果有机房级容灾的要求,但没有城市级容灾的要求,那么这种方案是最佳选择。
如果用户只有同城 2 机房而没有建设第 3 机房,可以考虑在同城内租借一个机房(甚至只租借部分机柜)来满足 3 机房的条件,并可以利用 OceanBase 的“日志副本”技术降低部署难度。
3 地 3 机房 5 副本方案
如果既有机房级容灾的要求,也有城市级容灾的要求,那么这种方案能全部满足,提供最高级别的高可用性。
如果用户的基础设施条件有限,无法满足上面几种方案的要求,但同时又要求机房级容灾能力或者城市级容灾能力,应考虑“集群间数据复制”方案。
最后,也必须意识到技术在不断进步,OceanBase 在不断进步,用户的 IT 建设也在不断进步。今天的最佳方案也许明天就能找到更好的替代者,因此我们必须以发展的眼光持续进化我们的技术方案,才能让 OceanBase 的用户在未来有更多更好的选择。在这个过程中,我们也非常希望和业界的朋友及广大用户有更多的技术交流和思想碰撞,共同推进分布式数据库技术下高可用及容灾方案的发展,谢谢!
本文转载自公众号蚂蚁金服科技(ID:Ant-Techfin)。
原文链接:
https://mp.weixin.qq.com/s/4zmwSJsEi4G7EiS9FefqtA
评论