多个不兼容版本数据同步(mysql 向 mongodb 数据同步)
背景
客观原因项目项目多版本共存,并且用户短时间内无法迁移到新版本上面并且数据会按照一定纬度(项目中成为业务)灰度到新版使用。 最终解决方案:业务数据未灰度前,只在旧版中对数据修改, 但是修改的结果在新旧版本中同时生效, 具体操作是未灰度到新版本中业务的数据修改操作都在旧版本中操作, 将变更的内容同步到新版中。
解决方案
主要面临的问题是以下:
- 旧系统数据变化同步实时性
- 数据关系的处理
- 边界数据的修改
旧系统数据变化同步
在版本灰度方案,给周边系统的承诺数据在新版本中生效的时间<=15s的前提下, 下面的方案都是不可用的:
- 由于旧系统使用的是mysql, 不提供数据变更通知功能
- 且旧版本本身数据变更推送服务是异步任务, 修改变更后从操作日志中提取变更再推送,延时比较大且推送事件的数据缺少部分数据无法使用。
- 定时全量同步更不符合预期, 原因:mysql中需要同步的数据总量多余5kw, 对于数据库压力过大和数据的实时性太低。
基于数据实时性的要求,必须要找一个基于事件数据增量同步的方案, 经过查找资料发现一个能实时读取MySQL二进制日志binlog, 并生成 JSON 格式的数据的工具maxwell。 maxwell 完全可以数据的变更推送出来做增量同步。
目前,关于数据同步实时性的可度量指标还没有收集, 正在开发中。实际使用统计数据同步小于1s。
数据关系的处理
- 数据合并及分裂, 主要新旧版数据字典定义差异, 造成多个table数据合并,分离,
- 数据形态发生变化,主要由于业务形态的变化,数据出现不兼容的情况
- 关联数据的变更, 主要是数据变更印象到所有相关联的节点数据。
这个主要是业务逻辑,需要基于一个数据为中心处理新旧系统数据库中多表, 特别是树形关联关系中某个节点删除后,下级节点数据处理。
边界数据的修改
- 新旧版本数据交换, 新-> 旧, 旧->新
- 未灰度业务的数据,在新版本修改,删除,新加数据
这个主要是业务逻辑,主要是确定一个规则,需要在开发前与PM,使用方确定好即可
开发中遇到问题
实时性如何保证?
maxwell能实时读取MySQL二进制日志binlog, maxwell 是以slave db instance 连接到mysql master db 上面直接获取binlog
如何保证mysql 数据变更事件不丢失
-
binlog 事件不丢失 maxwell 会落地存储当前处理mysql binlog offset, 重启后根据落地offset 继续处理 mysql binlog ,
-
事件处理不丢失 maxwell 支持将binlog 变更内容推动 kafka, RabbitMQ, Redis 等多种中间中,目前,使用是将数据推送到redis list,使用redis 两个list 做推送事件的ack,
redis ack 队列的实现:
1. maxwell push event redis list key1
2. 使用 redis RPopLPush 命令同获取到数据的同时放到 第二个list key2的队列中
3. 事件处理完成后,删除第二list key2中的数据, 如果出现意外情况,等待事件补偿方法处理list key2的事件
- 数据全量同步
作为一种补偿机制,每周执行一次,保证数据的准确性, 用户也可以强制发起基于业务的下数据同步
如何全量同步和增量同步数据冲?
全量同步时候, 暂停增量事件同步