Flink cdc技术在数据库同步方向的应用

项目背景

由于流量回放平台对录制环境和回放环境数据库一致性的要求很高,比如数据库的一致性误差在10分钟以内,数据库同步任务频繁等。mysqldump是mysql数据库提供的一个数据备份工具。mysqldump可以把mysql数据库导出成sql语句文件,并保存到磁盘上。mysqldump命令产生的.sql文件包含一系列SQL INSERT语句,可以用来进行数据恢复。进行数据导出和恢复的过程中耗费的时间较长远超过10分钟;且操作复杂,需要DBA协助。对于频繁的同步任务对DBA是不友好的。公司现有的数据库同步工具outter不支持全量数据同步;对应大数据量的数据同步,数据延迟比较大;对于大款表的同步频繁OOM。并且以上两种方式均不支持单租户级的数据同步。所以需要自己研发一款使用于流量回放平台的数据库同步工具,因此我们必须研发一款适用于流量回放平台的数据库同步工具。

需求分析

需要实现的目标

流量回放平台对数据库同步工具有以下要求:

  1. 源数据库(录制环境数据库)和目标数据(回放环境数据库)库的数据误差在开启录制时数据时间差在10分钟以内;
  2. 需要支持utf-8和ucs2(早期的大表使用的是此种字符集需要兼容)字符集;
  3. 可以自由选择需要同步的源数据库表和目标数据库表,且库名允许不一致;
  4. 由于不通环境的分库情况不同,还需要合并多个源库到一个目标库;
  5. 允许从源库同步单租户级别的数据至目标库;
  6. 支持源库数据增量同步至目标数据库;
  7. 支持单/多任务同步同一实例的多个数据库;
  8. 可以简单的操作就可以进行数据库任务同步,便于频繁数据库同步任务的执行。

技术方案的确定

CDC介绍

CDC的全称是Change Data Capture,是一种捕获增量数据的统称,目前主要应用在捕获数据库数据变更的技术,在数据同步、数据容灾、数据分发和数据集成等场景中。

目前业界比较流行的CDC技术解决方案主要分为以下两种:

基于查询的CDC
  • 离线调度查询作业,通过JDBC的方式发起一次查询请求,服务端根据查询SQL进行解析优化执行并返回相应的结果集;
  • 离线调度的方式天然的缺点是无法保证数据库的一致性和实时性,因为在查询的过程中数据可能发生了多次变化;
  • 对源数据库有侵入性,对源数据库有一定的IO压力,所以在使用过程中需要充分考虑到源数据库压力,协调执行时间和执行并行数,或考虑从备库进行数据同步;
基于日志的CDC
  • 实时消费日志,流处理。例如Mysql的日志文件binlog完整的记录了数据的变更,可以把binlog文件作为流得数据源;
  • 保证了数据的一致性,因为日志文件完整的记录了数据的变更;
  • 保证了数据的实时性,因为类似binlog日志的文件是可以流式消费的,提供的是实时的数据,只要处理得够快,就能保证源数据库和目标数据库的数据同步在秒级别
技术选型对比

对于常见的CDC开源数据库同步工具方案的对比,如下:
常见开源CDC方案比较

CDC方案比较

技术方案确定

通过以上的对比,可以看出得出以下结论:

  1. 在全量+增量同步的能力上是比较好的是Sqoop、Flink CDC、Debezium、Oracle Goldengate;
  2. 在1中支持断点续传的有Flink CDC、Debezium、Oracle Goldengate
  3. Oracle Goldengate主要是针对Oracle的;Flink CDC是基于Debezium开发的,并且进行了扩展增强,分布式架构,java语言开发,且社区比较活跃

所以我们决定基于Flink CDC来研发适用于流量回放平台的数据库同步工具(所有的表必须有主键)。
关于Flink CDC介绍,感兴趣的同学可以点击此处查看

功能实现

确定了技术方案后,我们就根据Flink CDC已有的功能上来实现自己的个性化定制,主要分为以下几个方面:

1.根据Flink CDC读取的数据进行解析,自定义反序列化方案

Flink CDC默认使用JsonDebeziumDeserializationSchema进行反序列化,把数据库的数据变更以json格式展示,并不符合我们的个性化需求,所以我们根据自己的需求定义了自己的反序列化器SqlDeserializationSchema,在此反序列器中我们做了如下实现:

1.把所有的操作分为DDL和DML语句

Envelope.Operation operation = Envelope.Operation.forCode((String) valueStruct.get(OPERATION));

2.把DML语句划分成不同类型的sql操作语句

public enum MysqlOperate {

    // ddl
    DDL,
    // dml
    INSERT,
    UPDATE,
    DELETE,
    // 未定义
    UNDEFINE,
    ;

}

在基于查询的CDC中只会转化成INSERT语句,在基于日志的CDC中数据的操作记录会转化为INSERT、UPDATE、DELETE语句进行处理。

3.UPDATE和DELETE操作需要根据主键来进行操作

List <Field> primaryKeys = (((Struct) sourceRecord.key()).schema()).fields();

4.分析Flink CDC给我们的数据格式,按照不通类型进行分析

  • 基于查询的CDC,使用JDBC查询的数据集
{"before":null,"after":{"config_id":1,"config_name":"Timothy Mendoza","config_key":"Paai6QCGyu","config_value":"RSVnKEpg7H","config_type":"U","create_by":"LnwDJwQL3l","create_time":997278609000,"update_by":"2008-09-20","update_time":1283015983000,"remark":"SvhrczrD0p"},"source":{"version":"1.5.4.Final","connector":"mysql","name":"mysql_binlog_source","ts_ms":0,"snapshot":"false","db":"xsy_flowreplay","sequence":null,"table":"sys_config_copy1","server_id":0,"gtid":null,"file":"","pos":0,"row":0,"thread":null,"query":null},"op":"r","ts_ms":1650611958990,"transaction":null}

  • 基于binlog日志的CDC数据变更的数据集-INSERT
{"before":null,"after":{"config_id":2,"config_name":"Timothy Mendoza","config_key":"Paai6QCGyu","config_value":"RSVnKEpg7H","config_type":"U","create_by":"LnwDJwQL3l","create_time":997278609000,"update_by":"2008-09-20","update_time":1283015983000,"remark":"SvhrczrD0p"},"source":{"version":"1.5.4.Final","connector":"mysql","name":"mysql_binlog_source","ts_ms":1650612061000,"snapshot":"false","db":"xsy_flowreplay","sequence":null,"table":"sys_config_copy1","server_id":1,"gtid":null,"file":"binlog.000007","pos":653648221,"row":0,"thread":null,"query":null},"op":"c","ts_ms":1650612061677,"transaction":null}
  • 基于binlog日志的CDC数据变更的数据集-UPDATE
{"before":{"config_id":1,"config_name":"Timothy Mendoza","config_key":"Paai6QCGyu","config_value":"RSVnKEpg7H","config_type":"U","create_by":"LnwDJwQL3l","create_time":997278609000,"update_by":"2008-09-20","update_time":1283015983000,"remark":"SvhrczrD0p"},"after":{"config_id":1,"config_name":"likenan","config_key":"Paai6QCGyu","config_value":"RSVnKEpg7H","config_type":"U","create_by":"LnwDJwQL3l","create_time":997278609000,"update_by":"2008-09-20","update_time":1283015983000,"remark":"SvhrczrD0p"},"source":{"version":"1.5.4.Final","connector":"mysql","name":"mysql_binlog_source","ts_ms":1650612078000,"snapshot":"false","db":"xsy_flowreplay","sequence":null,"table":"sys_config_copy1","server_id":1,"gtid":null,"file":"binlog.000007","pos":653648657,"row":0,"thread":null,"query":null},"op":"u","ts_ms":1650612078963,"transaction":null}
  • 基于binlog日志的CDC数据变更的数据集-DELETE
{"before":{"config_id":1,"config_name":"tangrui","config_key":"Paai6QCGyu","config_value":"RSVnKEpg7H","config_type":"U","create_by":"LnwDJwQL3l","create_time":997278609000,"update_by":"2008-09-20","update_time":1283015983000,"remark":"SvhrczrD0p"},"after":null,"source":{"version":"1.5.4.Final","connector":"mysql","name":"mysql_binlog_source","ts_ms":1650612156000,"snapshot":"false","db":"xsy_flowreplay","sequence":null,"table":"sys_config_copy1","server_id":1,"gtid":null,"file":"binlog.000007","pos":653649872,"row":0,"thread":null,"query":null},"op":"d","ts_ms":1650612157103,"transaction":null}
  • 基于binlog日志的CDC数据结构变更的数据集-新增表字段
{"source":{"version":"1.5.4.Final","connecto
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值