这是学习笔记的第 2142 篇文章

MySQL业务双活的初步设计方案_MySQL业务双活的初步设计方案

  在之前设计两地三中心方案时,提到了一个方案,在文章发布后收到了很多朋友的反馈,当然这个事情不是拍脑袋想的,我们最近在落实这件事情。 

  我们先来看下之前的一个简略版设计,这是基于分布式设计方案,可以引入数据组件syncer和writer,实现机房多活的业务需求,syncer和writer为数据的发布者和消费者,基于分布式协议进行处理。

在处理过程中有三类关键技术:

1)数据的处理基于分布式ID,能够唯一定位数据处理操作,并且该操作具备递增趋势。

2)同步组件的稳定性,同步组件可以理解为一种通用服务,需要考虑不同机房间的数据延迟和数据冲突处理机制,保证同步组件服务的稳定,高效。

3)同步组件的高可用,对于同步组件需要根据业务特点做权重处理,考虑不通IDC的业务情况,并重点考虑同步组件的数据冗余设计,保证发生异常时能够及时恢复数据。

此种方案短期内难以实现,但是长期来看,可以支持机房多活,业务价值更高。

MySQL业务双活的初步设计方案_MySQL业务双活的初步设计方案_02

 

当然在具体设计的时候,其实有很多现实的问题摆在面前,在经过了几次讨论和各个技术方向的对接讨论后,我设计了如下的方案。

MySQL业务双活的初步设计方案_MySQL业务双活的初步设计方案_03

 

我来做下解释,首先对于机房多活来说,我们设定的这个场景是源端和目标端,当然一个实例既可以是目标端也可以同时是源端。 

为了提高业务响应,我们的设定规则是遵循最终一致性,所以在业务场景接入的时候,对于高并发修改同一条数据的情况需要从业务规划层面避免。

 

从源端写入的数据会通过流转的方式进入目标端,而这个过程中数据的格式为了通用起见是采用了JSON来进行流转。

源端如何得到这些实时的数据变化,我们可以采用虚拟从库(virtual_slave)的组件来进行对接,这里可以参考的有canal,maxwell和mysql-python-replication,我们这里目前先行测试使用的是maxwell.

对于数据的流转,为了提高定制能力,我们需要加入过滤器(stream-filter)来进行过滤,同时在下发解析请求的时候可以通过路由的方式打到不同的队列里面,这里的队列可选方案有Redis,Kafka,RabbitMQ等,因为是双活方案,对标两地三中心,在数据写入队列时出现错误其实是直接会丢失数据的,所以在这一层面,是采用双通道的方式,即写入两个队列,两个队列是物理隔离的,数据在通道内自然有时间的先后。 

 

而缓存队列只是数据的一个流转节点,不需要保留过长的时间,所以数据下发之后就需要持久化,持久化代表着这个消息是完整唯一的,而多个通道同时写入就需要做去重的基本工作,这个如果采用MySQL方案可以很容易使用insert into duplicate的方式解决,如果为了提高多个通道并发写入的性能,可以采用TiDB的多个结算节点写入,而如果在兼容JSON格式时能够更加友好管理,可以考虑采用MongoDB的方案。 

 

 数据持久化之后就要开始消费了,我们可以采用类似Kafka的方案进行数据的消费,比如目标端有2个,则应该对已有的消息进行订阅推送,即分裂为两个不同的目标端数据。 

 

上面的流程中,我们遵循的一个基本设计方式是数据下推不回调,在存储持久化层实现了数据大完整性和唯一性之后,后续的下发流程是相对规整的。 

 

 

而如果数据的整个流转完成之后,如何快速应用,这里的设计方式是采用回调,我们可以采用通用接口的方式,来发布多个部署应用(APiInvoker)来进行数据的应用,如果出现错误则可以快速回到订阅入口进行再次稽核重试。

 

在这个过程中确实引入了很多的组件和可选方案,而整个方案的设计中也借鉴了很多Amdocs TRB的方案设计思想,在此向老东家致敬。 

 

这个初步方案已经在开始demo开发测试了,来初步验证整个复杂度和可行性,我们拭目以待,如果有好的方案,也欢迎留言交流。