TDSQL异地多活方案
目录
TDSQL异地多活方案 1
1.简介 1
2. 异地多活的架构选择 2
3. 分层的容灾架构 2
3. 同城的强同步架构 2
4. 主从+读写分离的异地多活 4
5. 多主的异地多活-双向同步 6
6. 多主的异地多活-多套主备架构 7
7.数据同步模式 9
8.总结 10
1.简介
本文详细描述TDSQL的同城强同步架构,并且在这个基础之上实现业务异地多活。异地的延时一般10毫秒(强同步延时会让业务难以接受)以上,否则直接采用类似于同城的强同步架构实现强同步就足够了。
2. 异地多活的架构选择
为了实现异地多活,在TDSQL里有3种常用的架构形式,下面会详细介绍:
- 主从+读写分离的异地多活,TDSQL的跨城采用跨城主备的方式进行部署,应用层基本上完全不用改造,业务层访问本城的接入层网关,然后网关自动对请求进行读写分离,以实现最佳的性能和准确的事务访问语义。适用于应用不做改造,而想实现跨城多活的能力
- 多主的异地多活,一般采用按用户的地域维度对整体的用户数据进行区分,不同的用户接入到不同的集群,集群之间采用双向或者多向同步,从而实现所有用户的多地接入,多地本地访问。
- 结合上面2种形式,通过多套主备的架构实现多活
3. 分层的容灾架构
业务服务层和TDSQL数据库独立分层,两层之间的容灾方式独立,业务服务层不关心底层TDSQL的情况,只需要访问本城TDSQL的接入层网关即可,以实现容灾方式独立和架构的最简化。
3. 同城的强同步架构
在正式介绍跨城的异地多活之前,先看看同城的架构,这个是数据访问和存储的基础,后面的跨城是在这个基础之上做扩展就好了。
架构分析:
TDSQL的数据层采用Master-Slave架构,proxy层提供无状态的跨IDC接入服务,已经是非常成熟的同城跨IDC容灾与双活方案。
对于某个SET来说,假如Master节点在IDC1,则在IDC2会有2个slave节点,并且采用基于raft协议的的强同步方案实现,保证主备数据完全一致,这样数据库层可以在IDC之间进行切换,并且事务能做到0丢失。对外的话,通过在两个IDC自动分了proxy层,因此业务服务可以在两个IDC进行接入,proxy会自动将写事务路由到主机上面。
容灾推演分析:
机器故障: 1.M故障:切换到S1,同机房内切换,业务服务会中断40秒左右(rto:40秒,rpo:0) 2.S1,S2,S3任意某个节点故障,不影响主机,业务无任何影响(rto:0,rpo:0) 数据中心故障:
3.IDC3故障:IDC3只部署了仲裁,对业务无影响。 |
4. 主从+读写分离的异地多活
在同城实现强同步架构之后,同城实现了任意接入和强大的容灾能力,如果需要异地也能接入和容灾+读写分离,则需要在异地再部署一套数据库,然后在2个城市之间的TDSQL实例建立主备关系即可,架构图如下(为了看的更加清晰,同城内部的图做了一些简化):
此方案两个城市之间的实例采用的是主从架构,业务可以在任意一个城市接入实现多活,读写事务都会正确路由到主机房,但是因为两地机房可能存在较大的延时,所以备城市承担的业务建议有较低的读写事务权重,避免延时太大,影响业务体验。但是作为优化,可以在备机房接入查询请求,在使用读写分离特性的时候可以使得大部分查询通过本城的TDSQL完成,实现非常好的扩展性和性能。
切换:当主城市故障的时候,可以通过TDSQL的切换接口进行跨城市级的手动切换,因为是对等的架构,所以切换之后应用的接入方式是完全不变的。注意:因为跨城同步是异步方式,所以在极端情况下RPO不为0,需要业务层有一定的校验机制来保证数据的准确性。如果作为常规的切换,可以先设置主城为隔离状态,然后触发切换,可以保证数据是完全一致的。
此方案适用于业务层不想对用户进行多区域拆分,但是又需要具备异地容灾切换的能力的系统。
5. 多主的异地多活-双向同步
如果业务层可以支持按区域对用户的数据进行调度或者按业务系统进行调度,则可以通过部署多套上面类似的TDSQL数据库来实现更加彻底的多活架构,架构图如下:
在这个架构上面需要业务层对用户的数据做一些拆分,比如部署在南北2个城市,则可以让北方的用户接入到北方的TDSQL集群,南方的用户接入到南方的TDSQL集群,从而实现应用层和数据的双活。
切换:当主城市故障的时候,可以让最前端的GSLB层将用户的请求调度到另外一个正常的城市,所以切换之后应用的接入方式是完全不变的。注意:因为跨城同步是异步方式,所以在极端情况下RPO不为0,需要业务层有一定的校验机制来保证数据的准确性。如果作为常规的切换,可以先设置某个城市为隔离状态,待数据完全同步完成之后,再在GSLB层做切换,保证数据是完全一致的。
风险点:如果用户调度异常,很有可能引起数据双写从而出现异常
此方案适用于业务层能对用户数据进行严格拆分,不会出现错误调度,以实现应用系统和数据库彻底的多活部署。
为了避免出现错误的数据调度,建议在上面架构的基础之上,不采用双向主备,而是各自采用主备的架构,即主城1的数据库在主城2创建一个异地灾备,在主城2的数据库在主城1创建一个异地灾备实例,如下节描述所示。
6. 多主的异地多活-多套主备架构
双向互相同步并且提供服务的架构非常简单方便,但是存在用户路由不正确引起数据双写的风险,因此建议跨城之间继续保持主备架构,提供多套独立的数据库来实现多活。为了结构清晰,下面的架构图省略了城市内部的IDC描述,真实部署是跟前面的结构完全一样需要跨IDC部署的。
同上面的架构一样需要对用户的数据做一些拆分,比如部署在南北2个城市,则可以让北方的用户接入到北方的TDSQL集群,南方的用户接入到南方的TDSQL集群,从而实现应用层和数据的双活。
业务层的部署:支持2种部署模式,左边是为同区域的用户使用不同的业务层,不同的业务层分别访问本区域固定的proxy即可,业务层实现非常简单,但是可能部署上会存在冗余。右边的架构是只要一套业务层,但是在业务层里面要根据用户信息路由到不同的proxy,实现稍微复杂一点,但是可能更省资源。
切换:容灾切换逻辑跟上面的双活一样
风险点:如果用户调度异常,只会引起读写事务的时耗边长,无数据脏写的风险。
此方案适用于业务层能对用户数据进行严格拆分实现多活,即使存在GSLB错误调度的情况下也不会影响数据准确性,因此在多活架构上更推荐采用这种策略,不过业务实现会稍微复杂一点,因为不同的数据库有不同的接入层,所以访问数据库的业务层也有两种部署模式,可以根据需要灵活选择。
7.数据同步模式
MySQL主备数据库节点之间的同步支持2种模式,可以根据需要进行选择。
模式一:原生主备同步模式
在这种模式下采用原生的MySQL同步协议,不依赖其他模块,时延能控制的最好,另外全量同步数据可以采用物理拷贝的方式,同步非常快。但是不灵活,比如在分布式的场景下,左边有3个数据库节点,则右边也要求有3个数据库节点,一一对应,因此更推荐在NoShard并且只是单向同步的情况下采用这种模式进行数据同步。
模式二:通过DTS进行数据同步
基本上跟上面的原生同步模式优缺点是互补,在这种模式下,通过DTS进行数据同步,会多一个模块,因此时延稍微会变大,并且重做一般采用逻辑方式进行全量同步数据,所以全量同步性能更慢一点。但是通过了DTS进行了主备的解耦,是的主备的架构可以丰富多用,比如主机采用3套数据库,备机可以根据需要部署任意的数据库,建议对于GroupShard或者双向同步的场景采用这种模式进行数据同步。
8.总结
1.TDSQL通过强同步机制提供同城跨IDC容灾部署,高一致性自动切换的能力,对于事务的安全,准确有非常好的保障,我们的大量的金融客户都会选择这种模式实现跨IDC容灾。
2.如果需要实现跨城多活,总计了三种可行的模式,分别是:
a) 主从+读写分离的异地多活,适用于应用完全不做任何改造,就可以实现跨城多活的能力。我们很多客户不想对业务改造,但是又想具备跨城多活和切换的能力,就会选择这个方案。
b) 多主的异地多活-双向同步,通过应用层根据用户维度做了区分之后,可以使得多套TDSQL数据库分别承载不同的业务进行读写事务访问,实现完全的多活能力,但是如果业务调度出现异常,可能存在数据异常的风险,一般不推荐使用。
c)多主的异地多活-多套主备架构,综合了a和b的架构,实现了完全的异地多活+读写分离的能力,并且即使业务层路由错误,也不会引起数据异常,如果应用层能配合修改,则这种方案是最推荐的模式。
最后总结了2种数据同步模式,NoShard并且单向同步建议采用原生主备同步模式;GroupShard或者双向同步建议采用通过DTS进行数据同步的模式。