马志宏 YashanDB高可用架构师
YashanDB V23.4 LTS版本增强了共享集群主备复制能力,本文将对集群主备复制机制的架构、部署模式、一致性实现进行深入探讨和技术分析。
共享集群主备复制的必要性
YashanDB共享集群本身提供高可用能力,可以有效解决服务器宕机、进程崩溃等节点级的故障问题。YashanDB V23.4 LTS版本针对存储层故障、所有实例不可用问题进一步优化集群高可用能力,增强共享集群主备复制能力。
集群主备复制通过发送redo进行数据同步,主库与备库的存储层相对独立。当主库存储层发生故障,可以将业务转移到备库,从而保障数据级的高可用性。因此主备复制机制不仅能有效应对存储层故障,还可以实现跨地域的数据冗余,满足异地备份的合规性要求。
图1 YashanDB共享集群主备部署示意图
共享集群主备复制的挑战
共享集群的主备复制逻辑要比单机更复杂,主要有以下几个方面的挑战:
- 性能影响:共享集群的每个实例会维护独立的redo文件,集群主库要发送多个实例的redo。同步模式下,一个事务提交时,可能要等待多个实例的redo被同时接收,并回复ACK。相比单机主备,对同步模式下主库性能影响较大。
- redo接收不对齐:主库多个实例独立发送redo给备库,备库接收速度有先有后。在某一瞬间,一个实例的redo发送快,另一个实例的redo发送慢,存在不对齐的问题。这种不对齐现象会影响事务提交以及备库回放逻辑。
- 数据一致性:备集群除了需要保证回放实例的查询瞬时一致性,还要考虑其他实例的查询一致性。这就需要备集群回放redo时,做好实例间事务信息和SCN的同步。
- 实例间故障处理:主集群的某个实例故障后,故障实例可能有一些redo还没发送给备库,此时需要其他实例托管故障实例的redo发送;同样的,备集群的接收redo实例故障后,也需要其他实例接管。
共享集群主备架构
YashanDB共享集群主备复制原理的架构图如下图所示,左边是主集群,右边是备集群。主备集群内部都是2个实例,主集群的2个实例支持读写业务,备集群的2个实例支持只读业务。
图2 共享集群主备复制架构图
在主集群中,每个实例都会启动发送线程,发送自己的redo日志;而在备集群中,只有一个实例会接收所有主集群实例的redo,并进行回放。备集群的其他实例不参与接收和回放redo日志,但是其余的模块与master实例一样,包括DC、GRC、Data Buffer等,因此备集群的其他实例也支持查询操作。
YashanDB V23.4 LTS版本做了性能优化。主集群和备集群都有日志缓存(log cache),主实例在执行redo刷盘时,会将日志写入日志缓存,发送线程可以直接从缓存中读取待发送的日志。备实例接收redo后先放到备库的日志缓存里,回放线程不需要从redo文件里读取日志,减少了读取IO操作,提高了整体的性能。
共享集群主备部署模式
YashanDB共享集群的主备复制支持一主多备部署,最多支持32个备集群。与单机主备复制一样,可以设置三种保护模式(最大保护、最大可用、最大性能),并且每个备集群都可以设置为同步备或异步备。
YashanDB V23.4 LTS版本中实现基于主备集群的“两地三中心”能力升级,支持生产中心主备集群部署。如图3所示,这是一个两地三中心部署模式,主集群是最大保护或者最大可用模式,同城部署一个同步备集群,保证数据不丢失(RPO=0),异地容灾中心部署一个异步备集群,不影响主集群性能。
图3 两地三中心部署示意图
此外,主备集群实例个数可以不对等。在部署时,主集群的实例个数可以比备集群实例个数多,从而减少部署成本。当备集群部署为单实例时,还可以直接使用本地磁盘替换共享存储,进一步减少部署成本。如图3,同城的备集群是2实例部署,而异地容灾中心为单实例部署,并且使用了本地磁盘。
共享集群redo同步一致性
与单机主备不同的是,主集群发送redo是多个实例同时发送给备集群,但备集群接收不同实例的redo的进度不一样。
如图4所示,在某一瞬间,可能实例1的redo发送更快,比实例2发送的多,即存在备集群的redo接收不对齐的问题,该问题会导致事务同步和回放逻辑更为复杂。
图4 redo接收对齐示意图
YashanDB共享集群在对页面进行跨实例修改时,会在redo中记录依赖关联信息。当备集群接收到redo日志时,会根据实例间的依赖性对redo日志进行对齐,以保证跨实例修改的页面redo是按照依赖顺序被正确接收的,从而保证主备集群最大保护模式下不丢失事务。如图4所示,V1、V2、V3是对同一个页面进行更改的3个redo日志,很明显该页面为跨实例修改页面,备集群在接收这类redo日志的时会进行依赖性对齐,等所有相关redo被接收后,将统一向主库发送ACK确认。
备集群在回放redo时,首先根据LSN(日志序列号)对所有实例的redo日志进行归并排序,然后放到一条回放队列里去回放,以此保证回放的顺序一致性。
备实例只读一致性
对于备集群来说,要想所有实例支持只读,并且满足一致性查询,需要注意3个要点:
- 回放瞬时一致性。备集群支持基于session的多线程并行回放,回放时模拟主库session执行顺序,事务瞬时一致性不会被破坏。
- 实例间SCN同步。备集群的SCN同步与主集群有所不同,备集群只有master实例回放redo日志,所以需要master实例给其他实例同步SCN。
- 事务可见性。备集群的master回放完事务提交的redo后,该事务处于PENDING状态。一直到该事务对应的提交SCN同步给所有实例后,该事务状态将变为COMMITTED。
图5 备集群内核组件示意图
YashanDB通过以上3个要点实现备集群支持多实例可读。如图5所示,由master实例维护事务状态,并同步事务信息给其他实例,其他备实例不产生脏页、不需要执行checkpoint。
主备故障切换
YashanDB支持Switchover和Failover两种主备切换模式。
Switchover表示主备集群角色互换,是计划内的切换。在备集群下发Switchover命令之后,主集群会断开所有session,进行降备,然后备集群升为主库。备集群升为主库的过程中,备集群上已经存在的session不需要断连,可以继续提供业务。
Failover发生在主集群所有实例故障之后,此时备集群升为主库接管业务。YashanDB的客户端支持TAF(透明故障转移),当备集群升主后,旧主集群上面的session能自动转移到新主集群上。因为采用了多线程并行回放,备集群回放redo的速度跟得上主集群redo产生的速度,不会积攒太多未回放的redo,因此Failover的RTO也很小。
图6 备集群Failover示意图
YashanDB共享集群主备性能实测
YashanDB的主备集群具有极小的RTO,为共享集群容灾提供了高可靠的解决方案。如下图所示,在一主两备、主集群两实例情况下,使用TPCC测试模型保持40W tpmC的压力测试10分钟。可以看到当kill主集群的所有实例并对2个备集群都下发Failover命令,此时测试结果为同步备的RTO为5.5s,RPO为0,异步备的RTO为12.8s,RPO为60ms。
最后,如果你对V23.4 LTS版本共享集群主备复制能力想要进一步了解,可以在"YashanDB公众号"后台回复小助手,添加微信获取讲师干货PPT。