上一期我们谈到了 OceanBase 如何保证数据的可靠性,以此为前提,服务可用性就成为了另一个焦点:如果某个服务节点发生了故障,用户不但希望数据不丢(RPO=0),而且希望服务能够尽快恢复(RTO 越小越好)。
在历史上,在传统数据库的高可用能力不足时,有很多种高可用方案是结合了硬件和操作系统的高可用能力,不过这些方案通常在架构上过于复杂,而且无法在数据库层面保证数据的一致性。随着数据库内置的高可用能力逐渐完善,用户也转向了数据库自带的高可用方案,典型代表就是“主从热备”技术,比如Oracle Data 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秒内完成服务的自动恢复。需要说明的是,具体的恢复时间和遇到问题的机器个数、表的分区个数、故障类型(机器硬件故障、网络设备故障等)都有密切的关系,所以上面说的服务恢复时间只是作为一个参考值,在某些特殊情况下也可能发生偏差。