缘起
2023年10月份的杭州云栖大会,围绕PolarDB-X分布式数据库,面向大型金融机构核心系统数据库改造实践做了一次技术分享《2023云栖大会-聚合话题:数智金融 数字金融核心技术硬核实践》,介绍了PolarDB-X分布式数据库在大型银行、股份制银行、证券系统、保险业务等场景落地的总结。
本篇文章是对云栖大会所分享内容的一个技术补充,期望从数据库架构设计的视角,分享下在大型银行落地PolarDB-X的经验,介绍Paxos多副本 + 传统两地三中心上的技术思考。
金融行业的容灾需求
在金融行业中,容灾是非常重要的,因为金融交易和金融数据的安全性和连续性对于银行和金融机构来说至关重要。金融行业一般有4级和5级容灾需求,分别代表了不同的容灾级别和要求,参考《分布式数据库技术金融应用规范 灾难恢复要求》、《信息系统灾难恢复规范 GB/T 20988—2007》:
4级容灾:较低级别的容灾需求,通常同城容灾,确保同城网络的冗余性和故障切换能力
5级和6级容灾:更高级别的容灾需求,要求多地容灾,需要建立多个数据中心,在主要数据中心不可用时能够快速切换到备用系统,针对6级在异地副本数、备份周期频率、恢复RTO上会有更明确的要求
一般银行的核心业务普遍要求5级容灾,考虑多数据中心的建设成本,当前金融行业普遍的5级容灾形态为两地三中心架构,典型的网络拓扑架构:
两地三中心对于数据库的需求
跨机房容灾,推荐Paxos/Raft多数派共识算法
在上一篇文章中《PolarDB-X:分布式数据库,挂掉两台机器会发生什么》,我们简单论证过对于数据有一定的重要性场景,都不应该选择主备架构的产品(包含mysql semi-sync半同步,也有网络降级为异步丢数的风险),而金融行业尤其重视机房级别的容灾(比如主机故障、断网脑裂等),推荐使用Paxos/Raft多数派协议的数据库,从多数派共识算法的原理层面可以很好的满足一致性要求。
目前主流分布式数据库基本都选择Paxos\Raft(包括其他变种协议),其共通点是,每份数据会存在多个副本,并且能够保证在一个副本挂掉的情况下,不影响可用性,并且不会出现任何一致性问题(脑裂、丢数据、丢更新等)。
本文同样无意去解析Paxos\Raft协议,我们需要思考结合两地三中心架构,进一步思考新一代基于Paxos多副本的数据库,如何满足金融的严苛要求。
我们将进一步探讨几个问题:
1、一个业务的两地三中心,同城和异地,数据库是一个实例还是多个实例,以及如何满足RPO和RTO?
2、业务对接分布式数据库有单元化诉求,单元化要求数据库切主同机房优先,如何满足单元化?
3、Paxos/Raft多数派共识算法,如何优化跨机房数据复制、以及如何满足机房故障场景?
4、分布式事务遇到两地三中心,是否会有数据一致性问题?
5、数据库日常的容灾演练能力,如何构建面向不同故障场景下的模拟演练?
1. 中心主实例 + 异地灾备实例
按照两地三中心的5级容灾,同城每个机房至少需要2副本 + 异地至少需要1个副本,因此基于Paxos多数派的需求,两地三中心比较合理的架构是采用5副本。
针对第一个问题,一个业务的两地三中心,PolarDB-分布式数据库的设计上是:中心主实例(5副本)+ 异地灾备实例(2副本),基于可以满足RPO/RTO以及故障演练场景的诉求,文章后续通过架构逐步演进的思路来介绍两地三中心的方案。
中心主实例
初始的架构设计
基于Paxos协议经常被咨询的一个问题:如果机房容灾,多数派副本挂了,异地容灾能否提供服务?
映射到两地三中心5副本的初始架构,思考RPO/RTO的相关问题:
1、中心机房A挂了,剩余3副本,可以满足多数派。此时,RPO=0且RTO<30,可以满足paxos多数派协议的自动切换
2、中心机房B挂了,如同上一条的A机房挂了的场景
3、中心地域挂了,机房A和机房B不可用,此时仅剩异地的1个副本,不满足多数派且异地RPO>0,这种场景下数据库比较难以自动恢复,需要结合RTO场景思考数据库的能力。
异地单副本启动
# 强制单节点,剔除所有follower
call dbms_consensus.force_single_mode();
这种故障恢复模式下,可以作为一种应急能力,但RTO的时间取决于运维同学介入 + 手工操作恢复的总时间(登录一堆数据库主机挨个重启节点),RTO比较难有严格时效性的保障。
同时,异地单副本启动模式对于故障演练场景的需求来看,即使有预期也会对当前业务有损(需要重建数据库),不太具备故障演练的能力。
异地灾备实例
架构形态:
1、中心主实例 + 异地灾备实例,采用数据异步复制 + 双向同步。
2、异地灾备实例,推荐选择为一个独立的Paxos 3副本实例,结合PolarDB-X的Logger副本类型,最后等价于2副本模式
PolarDB-X支持的副本类型:
基于异地灾备实例,继续考虑中心地域故障的场景:
1、中心主实例仅剩异地1副本,不满足多数派,此时中心主实例不可服务,可以快速切流量到异地灾备实例,可以满足RTO<1分钟
2、故障演练场景,可以切流量到异地灾备实例,此时基于双向同步的机制,异地灾备实例数据可以同步会中心主实例,演练过程对于数据没有太大的影响
2. 分布式 + 单元化
金融行业随着业务的发展,普遍都会有单元化的诉求,业务对于单元化的诉求:
1、业务单元化,将原本一个业务拆分为N个单元,每个单元承担部分流量,个别单元故障时可以隔离故障爆炸半径,避免影响业务整体。
2、分布式扩展性,将不同单元调度到不同资源上,实现业务的线性扩展性
业务对于单元化的诉求,通过分布式数据库的分布式拆分机制,有比较好的技术契合度,这也是金融行业对于分布式数据库比较热衷的一个原因。
单元化分片
PolarDB-X 分布式数据库,考虑单元化适配后,此时的架构设计:
如上图所示:
1、业务单元划分:中心地域2机房4单元,相当于每个机房有2个单元,每个单元有自己独立的主机硬件和交换机。
2、分布式适配:PolarDB-X数据库的数据节点DN的数量,推荐是单元数量的整数倍,比如4、8、12、16等。每个DN的多个副本,确保每个单元都有1个副本,同时需要调度不同分片DN的leader到对应的单元,最后的效果:每个单元内都有数据库全量数据,分片Leader各自均匀分布。
3、数据库和表,适配单元化的分片 和 对应的DN。比如总计4个DN(DN1~DN4),数据分片128份,单元化的数据分片规则就是:分片0~31(DN1)、分片32~63(DN2)、分片64~95(DN3)、分片96~127(DN4)。
4、单元化分片算法,适配业务单元调度。比如按照用户id进行单元化,按照hash算法进行适配,业务流量和数据库的分片单元进行对齐,最后达到业务流量访问同机房DB的效果。
这里基于单元化的结构设计,针对数据库有隐形的需求:
1、中心主实例,异地副本不能选为Leader,否则单元会有跨地域访问的场景,导致RT异常。
2、1个机房包含2个单元,如果遇到一个单元的DN副本故障时,优先切换到同机房的DN副本,尽可能保证业务和单元之间的同机房路由。
Paxos 选举权重
PolarDB-X分布式数据库,在Paxos协议部分引入了选举权重设计:
乐观权重机制,多数派共识算法Paxos在选举策略中优先发起选举容易成为Leader,引入权重后我们针对不同的节点引入随机延迟发起Leader选举的时间差,确保高权重的节点优先触发Leader选举。
强制权重机制,当某一新成为Leader的节点,发现自己不是所有节点中权重最高的节点的时候(当所有节点权重一致的时候,任意节点都是权重最高的点,所以此判定不生效),不会立刻放开写入,而是继续等待一个选举超时的时间段(称为禅让阶段),在禅让阶段会每隔一个心跳时间(比如1~2秒),向其它节点发送一次心跳探测。在选举时间段结束以后,如果收到其他权重比自己大的节点回包,即向回包节点中权重最大的节点发起一次Leader转移,确保高权重的节点成为Leader。
4个DN分片为例子:
整体权重按照9/7/5/3/1,权重策略说明:
1、同机房的单元分配9和7的权重,确保权重为9的Leader故障时,优先选择同机房的权重为7的副本
2、异地数据中心,分配到的权重为1,权重为所有副本中最低,确保Leader不会调度到异地机房
3. 跨机房复制
Paxos/Raft多数派共识算法,会涉及跨机房的数据同步,在两地三中心场景下,需要考虑两种case:
1、常态下,跨机房复制到同城或异地副本,相比于同机房,网络延迟差距比较大,如何优化对应的网络同步效率?
2、容灾场景(故障或者演练),中心一个机房出现不可用,此时原本的5副本,会变成只有3副本正常工作。虽然3副本也满足多数派,但涉及了异地机房的强同步,此时如何优化对应的网络同步效率?
Paxos 网络同步优化
PolarDB-X分布式数据库,在Paxos协议上针对高延迟网络做了大量的协议优化尝试和测试,并结合学术界现有的理论成果,通过合理的Batching和Pipelining,设计并实现了一整套自适应的针对高延迟高吞吐和低延迟高吞吐网络的通信模式,极大的提升了Paxos协议的性能。
1、Batching是指,将多个日志合并成单个消息进行发送;Batching可以有效的降低消息粒度带来的额外损耗,提升吞吐。但是过大Batching容易造成单请求的延迟过大,导致并发请求数过高,继而影响了吞吐和请求延迟。
2、Pipelining是指在上一个消息返回结果以前,并发的发送下一个消息到对应节点的机制,通过提高并发发送消息数量(Pipelining数量),可以有效的降低并发单请求延迟,同时在transmission delay小于propagation delay的时候(高延迟高吞吐网络),有效提升性能。
因Pipeling的引入,需要解决日志的乱序问题,特别是在异地场景下,window加大,加大了乱序的概率。PolarDB-X实现了一个高效的乱序处理模块,可以对底层日志实现屏蔽乱序问题,实现高效的乱序日志存储。另外,由于Paxos的内部状态复杂,PolarDB-X基于多线程实现Paxos、以及结合Group Commit技术,利用异步化技术来达到最大化的吞吐。
针对跨域网络的场景,我们用5台ECS机器模拟了两地三中心架构的5副本,来验证Paxos网络同步优化的效果:
两地三中心的跨地域网络,相比于同机房的多副本,性能下降差异在5~10%内。
副本数动态调整
两地三中心中,5副本多数派的复制组,需要>=3个副本完成同步响应,默认情况主中心的4副本会因为网络延迟的优势,优先在同城完成多数派的同步响应,多数派协议的延迟基本在1ms左右。但出现中心机房级别的故障后仅剩余3副本,会导致必须等待备份中心的副本也同步响应,导致多数派协议的延迟增加30ms。(比如常见的金融行业中主中心和备份中心的网络延迟在30ms左右)。
PolarDB-X分布式数据库,在Paxos协议设计上支持了副本数动态调整的能力,比如常见的副本数调整场景:
机房故障:5副本降级为3副本,引入downgrade_follower指令将follower角色降级learner角色,动态修改两个副本的角色
机房恢复:3副本升级为5副本,引入upgrade_learner指令将learner角色升级为follower角色,需要确保learner异步复制日志追平
单副本恢复多数派:1副本升级为3副本,引入add_follower指令动态新增节点,新节点会先成为learner角色,追平日志之后自动转成follower角色
中心单机房故障场景,模拟5副本降级为3副本:
1、通过控制台或者命令行,操作将对应机房的副本状态进行切换,动态降级为learner角色(异步复制,不参与多数派)
查看数据库内核多副本的状态,5副本变为3副本 + 2 Learner副本,此时多数派的投票变更为3副本
机房故障恢复后,可以通过副本重建的方式动态恢复
4. 分布式事务一致性
分布式数据库,是将数据存储在多个节点上的数据库系统。分布式事务能够保证多个数据库节点上的数据在事务执行过程中保持一致,避免因为网络故障、系统故障或节点失效等原因导致数据不一致的问题。因此,两地三中心架构下也要深度论证分布式事务的一致性问题。
在上一篇文章中《分布式数据库,如何有效评测国产数据库的事务一致性》,PolarDB-X在设计分布式事务机制时也讨论过容灾架构下的数据一致性问题。
容灾架构(两地三中心、同城3AZ),典型的容灾架构场景,比如考虑两地三中心的极端场景,中心地域挂了,切换到异地机房,异地机房的数据可以有延迟(RPO>0),但需要事务粒度的一致性,满足A和B上的账户总余额为100
如上图所描述,分布式多个Paxos复制组下,异地副本会出现复制进度不一致。如果遇到异地容灾切换,多个复制组各自的RPO不一致,最终会导致分布式事务的数据不一致。
额外思考一个问题:普通级别故障,比如:中心单节点故障、单机房故障,因为中心5副本的机制满足RPO=0,分布式事务的一致性是可以保证的。
CDC 事务日志复制
PolarDB-X分布式数据库,分布式事务针对容灾场景,引入日志组件CDC解决事务一致性的问题,CDC的基本工作原理:
1、CDC binlog文件:采集多个DN多副本的本地日志,进行汇众归并和排序,按照分布式事务的TSO版本进行乱序重排,最终产出分布式事务的binlog日志(兼容mysql binlog的完整格式)
2、CDC Replication协议:允许分布式数据库下游按照mysql主备复制的replication协议,比如:change master和binlog dump。
更多CDC的技术文章解读,可以参考:《PolarDB-X 全局 Binlog 解读》
结合PolarDB-X分布式完整能力,基于CDC优化中心主实例+灾备实例的复制机制,两地三中心的架构推荐:
异地就近访问
在两地三中心场景下,网络专线带宽是重要资源,需要在数据库的内部处理上尽可能减少不必要的数据访问,常见的网络访问诉求:
1、Paxos多副本之间的数据同步,必要的数据同步,可以采用压缩优化网络带宽
2、CDC事务日志的采集和同步
3、业务在异地访问数据库,比如报表或者对账
PolarDB-X分布式数据库,针对异地CN/CDC访问底下DN节点,引入了异地就近访问的设计,要求异地的组件就近访问同机房的DN,减少无谓的专线网络带宽访问。
设计1:CN异地就近访问DN
CN的默认规则是访问DN多副本的Leader节点,支持通过类似读写分离的机制访问follower副本。
在两地三中心场景下,CN引入异地只读实例的形态,产品定义:
1、异地CN默认访问异地的follower副本,获取元数据才会路由GMS Leader节点(主数据中心)
2、异地CN默认提供只读能力,禁止DML/DDL,避免用户在异地误操作(比如:异地写入会转发到主数据中心的Leader节点,因为网络延迟会带来事务提交的RT比较高,增加事务行记录锁的开销)
设计2:CDC异地就近访问DN
CDC的默认规则是访问DN多副本的Leader节点,采集Leader节点最新的本地binlog,再进行归并和排序,按照分布式事务的语义生成最终的分布式事务日志binlog。
在两地三中心场景下,CDC访问DN follower副本,因为网络30ms的延迟,在数据归并和排序时需要额外等待完整的分布式事务日志,增加一定的阻塞开销。CDC针对跨地域的网络场景做了针对性的优化,比如Batching & Pipeling处理、以及面向分布式的多流binlog能力。
针对跨域网络的CDC访问DN场景,我们通过ECS机器模拟了两地三中心场景:
CDC异地就近访问,相比于同机房的场景,性能约为30~60%左右,可以支持百万tpmC的业务(模拟TPC-C测试)。
一致性备份恢复
两地三中心架构,金融行业对于数据库的事务一致性要求同样适用于备份恢复,同时针对备份集也有特定的灾备需求,比如数据库备份存储需要对接银行内部的备份机,一般基于S3协议的存储设备,存储设备本身会有自己的灾备机制来容错。
PolarDB-X分布式数据库,在分布式备份上针对两地三中心的容灾需求,比如:5级容灾对于备份频率有明确的要求、以及全量+增量备份互补,因此对于分布式大规模存储下,除了备份一致性还有时效有要求。
分布式并行备份
阿里云上常见MySQL数据库基于xtrabackup物理备份速度在100~300MB/s,按照分布式128节点(每个节点1TB的存储容量来算),128TB的数据存储传统备份的时间124~372小时,这显然不符合备份时效要求。
PolarDB-X分布式数据库,技术上采用分布式的并行备份的策略,分布式128个节点,每个节点单独执行物理备份,总的128TB的数据基于分布式备份的时间理论值是1~3小时(会受限于备份存储介质的IO带宽上限)
分布式下的一致性
传统分库分表模式也会采用每个节点并发备份和恢复,但并发物理备份会导致多个节点之间没有任何关系,如果有涉及分布式事务的场景下,每个节点的独立备份并不保证事务的一致性,因此带来了很多数据一致性层面的问题。
PolarDB-X分布式数据库,结合分布式物理备份的前提下,引入了分布式一致性备份机制(《PolarDB-X 备份恢复》),基本原理就是在物理备份完成后,通过分布式事务埋点找补一段时间的增量日志,补齐不同节点上缺失的分布式事务日志。基于全量物理备份+增量逻辑备份的方式,确保分布式事务数据的一致性
异地RPO计算
两地三中心架构,对于异地容灾切换时需要精确统计对应RPO的情况,基于RPO的数据可以结合业务对账来回补对应的数据。
PolarDB-X分布式数据库,结合分布式事务、主实例+灾备实例的架构,分解了一下异地RPO详细计算的过程。
这里包含4个时间:
1、时间T1,业务在主中心实例上事务写入的最后一个版本时间戳(PolarDB-X有每秒执行的心跳SQL,确保T1时间约等于当前系统时间)
2、时间T2,分布式多个Paxos复制组,各自数据同步到异地,求取最小的版本时间戳,因为网络延迟,相比于时间T1至少约有30ms+的网络延迟
3、时间T3,构建分布式事务日志的时间,采集分布式的多个异地Follower,以最后的版本时间戳为上限,采集时间的延迟相比于T2约有100ms左右的延迟
4、时间T4,事务日志数据同步到灾备实例的最后更新时间戳,数据同步的延迟正常也在秒级左右
基于4个时间戳的定义,异地容灾RPO = T4-T1 ≈ T4-now(),常态情况下在秒级左右(1~3秒)。
PolarDB-X 异地灾备实例是独立于中心地域的架构,在异地容灾时可以通过灾备实例的时间T4来计算最后的RPO,常态下可以对接银行的监控来实时采集时间T1~T4。
5. 常态容灾演练
基于两地三中心架构,金融业务按照监管要求,会定期做容灾演练来提前验证,确保真实故障时可以正常切换。数据库在产品设计上,需要提供预期内容灾演练的能力。
PolarDB-X分布式数据库,梳理了容灾演练的多种场景,并提供基于DBStack管控的webUI和openAPI 容灾演练能力。
单DN节点切换
机房容灾切换
常见的故障演练操作
总结
业界有众多分布式数据库在金融银行领域,落地了两地三中心架构,但在架构的技术细节介绍上偏少,更多只是介绍基于Raft/Paxos 5副本的部署机制,这并不满足银行核心系统上线两地三中心的容灾诉求。
PolarDB-X 推荐的两地三中心架构形态:
本文以PolarDB-X分布式数据库,分享下在大型银行落地两地三中心架构的细节和思考,避免数据库研发、以及金融银行在技术选型时少走弯路,也非常欢迎大家提出宝贵的意见。
最后,回过头回答下最开始提出的5个问题:
1、一个业务的两地三中心,同城和异地,数据库是一个实例还是多个实例,以及如何满足RPO和RTO?
**推荐主备实例(主中心实例+异地灾备实例)的组合模式,可以更好满足容灾演练,中心地域容灾可以满足RPO=0且RTO<30秒,异地容灾因为异步复制RPO>0,但满足RTO<1分的诉求。
单实例模式下,采用两地三中心5副本的架构,中心容灾时可以满足RPO=0且RTO<30秒,异地容灾时因为仅剩单副本,需要手工以单节点模式重启数据库节点,RTO无法有效保障、以及缺少无损的容灾演练能力**
2、业务对接分布式数据库有单元化诉求,单元化要求数据库切主同机房优先,如何满足单元化?
分布式数据库与单元化可以有很好的契合点,数据分区和Leader分布可以与业务单元化流量对齐,结合选举权重满足同机房流量优先的诉求
3、Paxos/Raft多数派共识算法,如何优化跨机房数据复制、以及如何满足机房故障场景?
Paxos协议需要结合业务主流技术进行跨地域网络优化,同时副本数动态调整能力是一个核心诉求,从5副本动态降级为3副本,可以很好的解决机房故障时RT飙升的场景
4、分布式事务遇到两地三中心,是否会有数据一致性问题?
分布式事务在两地三中心容灾场景上,会出现事务数据同步不一致性的情况,可以引入事务级的日志复制解决,或者业务层避免使用分布式事务来绕过(市面上很多国产数据库交付的两地三中心更多是集中式数据库形态,比如基于mysql/mariadb、pg的单机主备形态)。
5、数据库日常的容灾演练能力,如何构建面向不同故障场景下的模拟演练?
需要构建全方案的容灾演练能力,从单元AZ/机房/地域、以及单实例、批量实例的容灾能力,需要提供webUI、以及openAPI方式适配现有银行系统