“数据不能丢,服务不能停”,能够说这句话道出了用户对数据库的核心能力的要求。然而,传统的商业数据库必须依赖高可靠的硬件才能实现数据可靠性和服务可用性。OceanBase做为一款成熟的企业级分布式数据库,基于普通PC服务器,就可以作到传统高端硬件环境下的数据可靠性和服务可用性,并且还能作得更好!跟咱们一块儿看看OceanBase的技术秘诀吧!数据库
说到数据可靠性和服务可用性,在数据库领域真是老生常谈的话题,能够说从数据库诞生之日起就如影随形。若是要用一句话来归纳数据库对数据可靠性和服务可用性的要求,能够借用OceanBase数据库创始人阳振坤老师的一句话:“数据不能丢,服务不能停”。能够说,这句话也道出了用户对数据库的一个核心能力要求:除了功能完善、使用方便以外,还要绝对安全、足够健壮。能够说,为了知足这两个看似简单的要求,在数据库领域诞生了大量的技术和论文,也让无数人绞尽了脑汁。安全
在传统的商业数据库产品(如Oracle、DB2)中,虽然也有一些行之有效的软件技术(如Redo Log、主从热备技术等)用来提升数据可靠性和服务可用性,但总体来讲对硬件的稳定性有很强的依赖。而传统的企业级服务器(如IBM 的Mainframe、AS400、Power等)和EMC、IBM等厂商的高端存储产品,可以很好的保证硬件的稳定性,所以也就成为了Oracle为表明的传统数据库产品的理想平台,这也就是"IOE"一词的由来。能够说,I和E的重要职责就是保障O的稳定运行。服务器
不知不觉间,IT世界进入PC服务器的时代。和传统架构相比,PC服务器能下降成本并带来扩展性上的便利,逐渐成为以互联网为表明的众多企业用户的首选。但PC做为服务器也为用户带来了一个棘手的问题,那就是硬件(服务器、内置磁盘、网卡等)的可靠性明显降低了。虽然也有一些其它机制(好比RAID、外挂磁盘阵列等)能够用来改善这种状况,但不能从根本上解决问题。微信
近些年来新兴的数据库产品,尤为是分布式数据库,几乎无一例外地采用了PC服务器架构,那在这种相对不稳定、不可靠的硬件条件下,分布式数据库如何保证数据可靠性和服务可用性呢?对习惯了传统高端硬件稳定性的企业用户来讲,这个问题的答案将直接决定业务要承受多大的风险。网络
针对这个问题,OceanBase给出了很是明确的答复:在PC服务器架构下,OceanBase不但可以知足传统高端硬件环境下的数据可靠性和服务可用性,并且还能作得更好!能够说,新技术趋势(PC架构)所带来的问题(硬件可靠性下降),反而倒逼了技术自身的演进,你们开始认真思考如何在“不可靠”硬件环境下保证数据的“可靠性”,并进一步保证服务的“可用性”。最终的结果,是更多的从软件层面引入保障机制,来弥补硬件环境的不足。后文将从多个方面来阐述OceanBase具体是如何作的。架构
在传统数据库中,有几种经常使用的手段来保证数据可靠性:运维
1)Redo Log分布式
2)主从热备性能
3)备份/恢复操作系统
4)存储层数据校验
这些技术能够从很大程度上提升数据的可靠性,但彷佛都没法作到完美(即RPO=0),也就是没法保证数据彻底无损,下面咱们简单分析一下缘由。
首先看Redo Log。采用Write-Ahead-Log(WAL)模式的Redo Log能够保证数据库中已提交的数据不会丢失,若是已提交的数据还在内存中就发生了宕机等意外,利用Redo Log能够恢复这些还未持久化的数据。但这里有一个前提,就是Redo Log自身必须绝对可靠,若是Redo Log所在的存储发生损坏,那么这一前提便不复存在。
所以,Redo Log所带来的数据可靠性其实取决于硬件的可靠性,说到底仍是要依赖高端硬件。此外,若是是已经持久化的数据遇到了硬件损坏(好比“坏页”问题),而且对应的RedoLog已经被覆盖,那么Redo Log也无能为力了。
有了主从热备技术(好比Oracle DataGuard,IBM DB2 HADR等)以后,Redo Log能够写两份甚至多份了,即便主节点遇到硬件故障,仍然能够用备节点的RedoLog来恢复数据,看上去能够作到RPO=0了。但其实否则,虽然主从热备技术一般都提供“数据强同步”的手段(好比OracleData Guard中的Max-Protection模式,IBMDB2 HADR中的Sync模式)来保证RPO=0,但实际系统中几乎没有人采用。为何呢?缘由很简单,这种模式下一旦备节点发生故障,或者主备之间的网络发生故障,那么主节点的正常交易就会受拖累;换句话说,备节点不但没有提升总体稳定性,反而下降了总体稳定性,得不偿失。因此,在实际生产系统中部署过主从热备的朋友都知道,几乎没有人会采用数据强一致模式,也就没法作到RPO=0。
除了Redo Log之外,咱们还有用来保底的“备份/恢复”手段。但备份/恢复机制在时效性上有明显缺陷,只能最为应对最差状况的“最后一发子弹”,不到万不得已毫不使用。并且,备份文件的可靠性最终依然是依赖硬件的可靠性。
最后,数据库的存储层一般都会有数据校验机制,用来检测存储层的“静默错误”和潜在的软件错误。但数据校验机制更多的是用来在过后发现错误,没法预防或者解决错误,后面咱们会介绍OceanBase如何将这种技术和其它机制结合起来,以提升总体的数据可靠性。
综合上面的分析,能够看到传统数据库最终仍是要依赖高端硬件的可靠性来保证数据的可靠性,只依靠数据库自身的能力是没法保证RPO=0的。
那么在PC服务器的环境里,硬件的可靠性明显不足,OceanBase这样的分布式数据库又是如何来保证数据可靠性呢?
前面提到过,咱们更多的是在软件层面引入保障机制,好比以Paxos(以及后面衍生出来的Raft)为表明的“分布式一致性协议”。OceanBase充分利用了Paxos协议,并将Paxos协议和传统的WAL机制结合起来,每一次Redo Log落盘时,都会以强一致方式同步到Paxos组中多数派(leader+若干follower)副本的磁盘中,这样作有两个好处:
1)在Paxos组中任意少数派副本发生故障的状况下,剩下的多数派副本都能保证有最新的Redo Log,所以就能避免个别硬件故障带来的数据损失,保证RPO=0。
2)Paxos协议中的数据强一致是针对“多数派”副本而言,而不像主从热备那样要求“全部”副本的数据都保持强一致。若是Paxos组中有少数派follower副本发生故障,剩下的多数派副本(leader+若干follower)之间的数据强一致彻底不受影响,这就解决了前面提到的问题:主从热备模式下备副本故障拖累主副本的可用性。
综合以上两点,OceanBase利用Paxos协议能够保证RPO=0,且没必要担忧应用的性能会受到影响,这也是OceanBase和传统数据库在数据可靠性方面最显著的不一样点。
前面提到过的“数据校验”机制,在众多工程实践中已经被证明为一种行之有效的机制。可是,若是要在采用Paxos协议的分布式数据库中实施数据校验机制,状况将更加复杂:除了要关注单个物理节点的“静默错误”,还要保证多个副本之间数据的一致性。
假设网络传输出了问题,致使错误的数据从leader副本发送到了follower副本;若是follower副本在不知情的状况下,将这些错误的数据当成正确的数据存储起来,一旦leader副本发生问题,而有错误数据的follower副本又接管了服务,那么就直接形成了用户的数据损失。OceanBase也在存储层引入了数据校验机制,但咱们加入了更多的技术手段以免上述问题,大体包含如下内容:
1)Redo Log的数据校验
首先,Redo Log在落盘的时候会加上数据校验信息,用来应对可能发生的磁盘静默错误。此外,为了保证一个Paxos组中多个副本之间Redo Log的一致性,Redo Log在leader发送和follower接受时都会检查数据校验信息,避免网络传输问题致使的数据错误。
2)数据盘上的校验信息
和Redo Log相似,数据盘上的数据也会有校验信息以应对磁盘静默错误。但因为OceanBase是经过Redo Log实现Paxos组中多个副本之间的数据同步,数据盘上的数据并不会经过网络传输在多个副本间同步,所以不须要副本间的实时校验。
3)副本间的检查点一致性校验
刚刚提到了,OceanBase不会对数据盘上的数据作副本间的“实时”校验,但咱们仍是会在一些特定的检查点,对多个副本之间的数据盘作一致性检查。这个检查点选在了OceanBase的“每日合并”点,主要的缘由,是每日合并动做自己就要对大量数据作归并和从新写入,恰好能够利用这个时机作数据的一致性检查。经过这个检查,进一步在存储层确保了多个副本之间的数据一致性,提升了数据可靠性。
4)数据表和索引表之间的数据一致性校验
对于有关联关系的数据对象,OceanBase会作额外的检查以保证它们之间的数据一致性。比较典型的例子就是索引和它的数据表,OceanBase会在一些特定的检查点(如每日合并点)作索引和数据表之间的一致性检查,进一步提升数据可靠性。
5)按期作数据校验信息检查
上面提到的一些数据校验措施(好比Redo Log和数据盘上的数据校验信息),主要目的仍是在数据中埋入校验信息。但光有校验信息是不够的,还要可以利用校验信息及时发现磁盘的静默错误,不然就只能等到访问数据的时候才能发现错误,为时已晚。为了应对这个问题,OceanBase在后台有按期的检查任务,在不影响在线业务的前提下,利用数据校验信息主动检查磁盘静默错误,一旦发现错误会及时通知用户,尽快采起补救措施。
最后,OceanBase也和传统数据库同样提供完善的备份/恢复机制,包括全量备份功能和增量备份功能。并且OceanBase的增量备份是以不间断的后台daemon任务形式持续进行,彻底不影响在线业务,下降了运维操做的复杂度。不过从分布式数据库的运行实践来看,在实际系统中极少发生Paxos组中多数派副本同时毁坏的状况,所以基本不会真正用到备份来恢复数据。
在数据可靠性有保证的前提下,服务可用性就成为了另外一个焦点:若是某个服务节点发生了故障,用户不但但愿数据不丢(RPO=0),并且但愿服务可以尽快恢复(RTO越小越好)。
在历史上,在传统数据库的高可用能力不足时,有不少种高可用方案是结合了硬件和操做系统的高可用能力,不过这些方案一般在架构上过于复杂,并且没法在数据库层面保证数据的一致性。随着数据库内置的高可用能力逐渐完善,用户也转向了数据库自带的高可用方案,典型表明就是“主从热备”技术,好比OracleData Guard、IBM DB2 HADR等。
可是,主从热备技术在高可用上有一个很难解决的问题:当主节点故障的时候,如何让备用节点快速接管服务。若是让备用节点判断主节点的状态,而且在主节点故障时“自动”接管服务,那么就会面临一个致命的问题,就是“脑裂(Split-brain)”:备用节点和主节点同时提供服务了,两个节点间的数据将再也没法保持一致。
为了不脑裂问题,数据库的主从热备机制都不会提供“备库自动接管服务”的能力,备库的接管动做要引入人工决策的流程,须要人为在备用节点发起服务接管的动做。这样一来,RTO就会达到数十分钟甚至以小时计。为了不脑裂问题,同时又减少RTO,有些数据库产品引入了自动failover的机制,好比Oracle数据库的Fast-Start Failover(FSFO);但因为引入了额外的组件或者服务,整个解决方案的复杂度明显增大,并且这些组件或者服务自身的高可用又成了新的问题。整体来讲,因为主从热备的本质没有发生改变,只是额外引入了第三方仲裁者的角色,因此这种方案并无解决根本问题,也不能100%保证避免脑裂。
前文已经提到, OceanBase利用了Paxos协议中的多数派共识机制来保证数据的可靠性,在高可用方面,OceanBase是利用了一样的机制。首先,根据Paxos协议,在任一时刻只有多数派副本达成一致时,才能推选一个leader,其他的少数派副本则不具有推选leader的资格。
其次,若是正在提供服务的leader副本遇到故障而没法继续提供服务,只要其他的follower副本知足多数派而且达成一致,他们就能够推选一个新的leader来接管服务,而正在提供服务的leader本身没法知足多数派条件,将自动失去leader的资格。所以,咱们能够看到Paxos协议在高可用方面有明显的优点:
1)从理论上保证了任一时刻至多有一个leader,完全杜绝了脑裂的状况。
2)因为再也不担忧脑裂,当leader故障而没法提供服务时,follower即可以自动触发选举来产生新的leader并接管服务,全程无须人工介入。
这样一来,不但从根本上解决了脑裂的问题,还能够利用自动从新选举大大缩短RTO,能够说完美解决了主从热备技术在高可用上所面临的难题。
固然,这里面还有一个很重要的因素,那就是leader出现故障时,follower能在多长时间内感知到leader的故障并推选出新的leader,这个时间直接决定了RTO的大小。在OceanBase中,为了可以及时感知Paxos组中各个副本(包括leader和follower)的状态,在各个副本之间会有按期探活的消息。另外一方面,探活机制虽然可以检测到节点的故障,可是在网络不稳定的状况下,也可能因为偶发的探活消息丢包而产生“误报(False-alarm)”的状况。为了不误报对系统稳定性带来的影响,OceanBase也采起了不少应对措施:
1)首先,探活消息的周期必需要合理。
若是周期太长就不能及时感知到节点故障,若是周期过短就会增大误报的几率,并且也可能会影响性能。目前在OceanBase中的探活周期为10秒左右,确保能及时感知到节点故障,而且也不会频繁产生误报。
2)其次,要可以容忍偶发性的消息丢包,减少误报的几率。
具体来讲,OceanBase不会因为一次探活的失败就认定某个节点发生了故障,而是在连续屡次尝试都失败后才确认真正的节点故障。这就有效避免了偶发性消息丢包所致使的误报。
3)若是真的发生了误报,须要将影响范围降到最小。
OceanBase将Paxos组的粒度下沉到了表的分区一级,也就是每个分区都会有一个Paxos组,用来维护这个分区的多个副本之间的leader-follower关系。若是因为少许网络丢包致使“某个分区”的探活消息没有收到回复,那么受影响的只是这个分区,同一台机器上的其它分区会照常工做,这就有效地控制了问题的影响范围。
4)某些特殊状况的处理。
举个例子,若是某台机器出现间歇性故障(好比网卡或者操做系统出了问题),致使这台机器频繁发生网络传输故障,就会使这台机器上全部的leader副本持续受到影响。这种状况下,OceanBase能够经过设置特定参数限制这台机器暂时不参与leader选举,这样就有效地起到了隔离做用,避免了局部故障对整个集群的可用性形成持续影响。
在具有了上述这些处理机制后,OceanBase目前已经能作到最多10秒钟检测到服务节点异常,并在10~30秒内完成服务的自动恢复。须要说明的是,具体的恢复时间和遇到问题的机器个数、表的分区个数、故障类型(机器硬件故障、网络设备故障等)都有密切的关系,因此上面说的服务恢复时间只是做为一个参考值,在某些特殊状况下也可能发生误差。
前面说到的内容,更多的仍是从逻辑架构上介绍OceanBase如何实现数据可靠性和服务高可用。但实际应用中,除了逻辑架构以外,还必须考虑到系统部署时的物理分布状况,不然就没法充分利用Paxos协议所带来的优点。这就衍生出了机架容灾、同城机房容灾、异地城市容灾等诸多和容灾相关的概念。
OceanBase微信公众号中已经介绍了经常使用的容灾方案,有兴趣的朋友能够参考公众号里的文章:
到目前为止,咱们已经介绍了OceanBase中关于保证数据可靠性和服务高可用的一些基本原理。原理看上去简单,但因为分布式数据库的网络复杂性以及PC硬件的不可靠,在实际使用中会发生形形色色的各类异常状况,任何一个细节处理很差都会形成严重后果。
通过在蚂蚁金服的大大小小、成百上千个系统中多年的打磨和锤炼后,OceanBase已经逐渐完善了众多的处理细节,造成了有效的机制来保证数据可靠性和服务可用性。并且,这套机制已经在众多实际系统中获得了很好的验证,尤为是支付宝和网商银行这种“线上数据就是所有,一个字节也不能丢”的金融级核心系统。
所以,今天OceanBase能够说已经突破了传统单点数据库在数据可靠性和服务高可用方面的限制,让用户的数据更安全,服务更稳定!