基于MySQL的高可用准实时的数据同步方案

下载网站:www.SyncNavigator.CN 
 客服QQ1793040
----------------------------------------------------------


关于HKROnline SyncNavigator 注册机价格的问题

 

HKROnline SyncNavigator 8.4.1 非破解版 注册机 授权激活教程
 

 

随着公司业务的发展,经常需要做一些数据同步或者数据变化监控的工作,举例:

1.  订单数据需要同步到其他业务系统

2.  业务数据需要同步到数据分析部门做分析

3.  数据库的数据需要同步到全文搜索引擎

经常使用的方法有如下几种:

1.  保持双写,即更新数据同时,更新缓存,更新搜索,提交数据到其他业务线

2.  通过定时任务扫表同步

3.  引入消息队列,生产者与消费者分开处理

以上的方案多多少少都存在一些弊端:无法保证双写成功,影响核心业务代码可读性,难以保证实时性等。

由于公司主要的存储是MySQL,因此 融360技术团队 引入CDC(change data capture)解析MySQL  Binlog,解决以上问题。目前在公司有以下业务场景使用:

1.  消息的pub/sub

2.  异构数据的同步

3.  MySQL在线 DDL

4.  MySQL在线分库/分表的平滑迁移

5.  大数据准实时ETL

业界方案目前也有许多方案支持MySQL日志解析,但如果要用于生产环境,主要存在几个问题。

1.  单点问题,缺少高可用支持

2.  重启程序不平滑

3.  不支持表过滤,比如只需要监控特定表的场景

4.  缺乏完善的监控

5.  缺乏多集群多实例的统一管理

6.  使用不够方便友好

项目介绍CDC基于MySQL数据库增量日志解析,将MySQL Binary Log事件(插入/删除/更新)转换为JSON格式数据发送到RabbitMQ或其他MQ(如Kafka),业务端只需要进行增量数据订阅和消费。目前已经在超过10个MySQL实例上稳定运行超过36个月。其中MySQL日志协议解析基于开源项目:

https://github.com/shyiko/mysql-binlog-connector-java

Features

  • 高可用,集群部署
  • 表级别过滤
  • 支持几乎所有MySQL字段解析(MySQL 5.6以上版本未完全覆盖测试)
  • 自动保存Binary Log位置节点,平滑升级重启,数据保证高可用
  • 配置集中化管理
  • 运行状态监控
  • 动态加载表配置
  • 支持添加多个导出数据源,方便扩展到其他消息队列
  • 支持顺序优先/性能优先,可根据业务特点选择使用
  • 支持 RESTFUL 接口,方便扩展

设计实现如下

整体架构基于MySQL的高可用准实时的数据同步方案

基本原理可以将CDC看作是一台从库,它会向主库发送 binlog dump 指令,主库就会将 binlog event 源源不断的发送过来。

主线程解析binlog事件,保存到内存队列,工作线程读取对应队列事件,分发事件。

分发策略根据业务场景不同,提供2种发送策略:

1.  多个线程分发事件(不会严格按照SQL执行顺序),提高分发效率,保证性能,侧重于关注数据变化的场景

2.  保证事件到达顺序,单线程发送事件,侧重于对准确性要求极高的场景

消息接收器通过注册不同消息接收器,来支持发送到不同MQ。支持注册多个消息接收器。消息接收器如果有特殊需求可以实现定制化。

下面主要介绍下RabbitMQ消息接收器原理。

注册RabbitMQ消息接收器后,CDC会将消息发送到RabbitMQ的一个 TOPIC 类型的exchange中。

根据消息对应的routing key,非常方便的将消息发送到指定的队列中。routing key生成规则为:

 database(数据库名).table(表名).action(对应动作,insert/update/delete)

如果是分表,为了避免在rabbitmq中添加多个绑定关系。routingkey生成规则为:

database(数据库名).{table(表名前缀)}.action(对应动作,insert/update/delete)

比如数据库admin中orders分表为orders_1,orders_2,则对应的routingkey为admin.{orders_}.action

基于MySQL的高可用准实时的数据同步方案

设置入队规则的步骤基本如下:

1.  新建队列,比如 all-users-binlog

2.  在指定exchange中建立绑定关系,如上图示例

表过滤Binlog事件dump过程中会得到数据库中所有表的变更记录。在实际使用中,可能只需要关注特定表(比如订单表)的变更事件。为了提升性能,引入了事件过滤逻辑,通过配置对应数据库+表名,过滤binlog事件。

基于MySQL的高可用准实时的数据同步方案

比如配置过滤逻辑为admin.orders,消息接收器收到消息只会包含orders表的消息。

对于数据库物理分表,比如当数据库订单表分了100张子表的时候,这时候配置过滤逻辑会是一件麻烦的事情。为了避免配置多个表,引入前缀匹配逻辑,只需要保证分表前缀相同,即可简化为一条配置。比如订单分表配置可以简化为admin.orders_{suffix},这样配置之后,只要匹配orders_前缀的表,均可以捕获到变化,这里的“{suffix}”是固定值,不能更改。

过滤逻辑可见上面面示意图,图中pos:1018为事件在MySQL binlog中的位置点,位置点小代表SQL执行顺序靠前。

你可能会注意到上文提到的RabbitMQ,如果我们只绑定特定的表,也可以达到同样目的。但是这样做有2个缺点:

  1. 会增加无用的消息发送
  2. 性能会有损耗,增加无效事件解析

当然如果想监听从库所有事件,不配置表过滤即可

平滑重启实际生产环境使用过程中,如果重启程序后,不能从上次停止的binlog 位置读取,重启期间数据库(此时监听数据库保持运行)增量数据就会丢失。为了避免上述问题,实例运行期间每隔5秒定时保存已发送成功的binlog节点位置,程序重启自动读取上次保存的位置节点继续解析binlog事件,当然这样会带来数据重复,需要业务使用者保证消息的幂等。

高可用正常情况下,监听一个从库只需要启动一个CDC实例,但如果此时机器宕机,就会造成服务不可用,这种异常情况在生产环境没有容错方案是不合理的。

为了保证CDC服务的高可用,会同时在多台服务器启动CDC,并引入分布式锁,保证同时只有一个实例连接到MySQL解析Binary Log,其他的实例为备选。如果主节点宕机,则备选节点通过竞争获取到锁,连接到MySQL,保证服务继续使用。

基于MySQL的高可用准实时的数据同步方案

运行步骤如下:

  1. 尝试获取分布式锁
  2. 获取成功,则连接数据库,获取Binary log事件流
  3. 获取失败,则主线程等待5秒后,回到第1步

表过滤配置动态加载程序重启会导致数据延时(分钟级别),要尽量避免不必要的程序重启。

生产环境中经常遇到这样的场景,给某个实例新加一张表,如果要让新加的过滤配置生效,就需要重启程序。显然这种频繁变更的配置,需要通过重启程序来生效是不合理的。

因此CDC支持动态添加表和删除表过滤配置,实时生效。

监控和平台化随着更多业务线接入CDC,对CDC的管理成为棘手的事情,如不知道实例具体在哪台机器运行,运行是否正常(位置点是否更新),配置管理更新和业务接入等等。

主要通过下面2点来解决管理问题:

  1. 实例运行注册制,监控实例运行状态。
  2. 配置和数据中心化存储,动态下发来规范配置管理。

化分布式锁、配置存储、加载上诉分布式锁和数据存储,历史版本是通过redis来实现,但是redis并不适合这样高可用场景。

综合考虑,开源版本选用 ETCD,ETCD 是一个高可用、强一致性的服务发现存储仓库。CDC通过ETCD主要实现下面几个功能:

  1. 服务注册
  2. 分布式锁
  3. 保存binlog名字和位置节点
  4. 配置管理
  5. 配置动态加载(reload)

消息格式消息包含3种类型:

insert,update,delete。

数据示例:

  • INSERT

基于MySQL的高可用准实时的数据同步方案

基于MySQL的高可用准实时的数据同步方案{

“database”:”test”,
“createtime”:1525319434400,
“data”:{
“longtext”:”test longtext”,
“date”:”1556121600000″,
“year”:”2019″,
“bit”:”1″,
“point”:”POINT (123.46202 41.2301)”,
“smallint”:”23″,
“datetime”:”1556007145000″,
“text”:”test text”,
“fload”:”5.55″,
“bigint”:”55″,
“tinyblob”:”测试test tinyblob”,
“timestamp”:”1524801357000″,
“multipoint”:”POINT (123.46222 41.201)”,
“mediumint”:”5″,
“set”:”a,c,d”,
“mediumtext”:”test mediumtext”,
“double”:”5.555″,
“tinytext”:”test tinytext”,
“varchar”:”test varchar”,
“tinyint”:”7″,
“multilinestring”:”LINESTRING (0 0, 13 16)”,
“id”:”6″,
“enum”:”a”,
“mediumblob”:”测试test mediumblob”,
“varbinary”:”convert(binary,’8280′)”,
“multipolygon”:”POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (5 5, 7 5, 7 7, 5 7, 5 5))”,
“blob”:”测试test ccblob”,
“polygon”:”POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (4 4, 7 4, 7 7, 4 7, 4 4))”,
“binary”:”convert(binary,’828′)”,
“char”:”test char”,
“longblob”:”测试test longblob”,
“geometry”:”POINT (108.998710632 34.258825935)”,
“time”:”-10800000″,
“geometrycollection”:”POINT (10 30)”,
“decimal”:”5.56″,
“linestring”:”LINESTRING (0 0, 10 10, 20 25)”
},
“action”:”insert”,
“uniqid”:”fe5be0ecaee15e7331a9c841df5c0b91″,
“table”:”cdctest”
}

  • UPDATE

基于MySQL的高可用准实时的数据同步方案

{

“database”:”test”,
“createtime”:1525319725963,
“data”:{
“before”:{
“id”:”6″
},
“after”:{
“mediumint”:”3″,
“decimal”:”5.50″,
“bigint”:”2″,
“timestamp”:”1525319725000″
}
},
“action”:”update”,
“uniqid”:”8e9c8af3acc6a7e6ff0d6c23608b4eaf”,
“table”:”cdctest”
}

  • DELETE

基于MySQL的高可用准实时的数据同步方案

{

“database”:”test”,
“createtime”:1525319817439,
“data”:{
“id”:”6″
},
“action”:”delete”,
“uniqid”:”9f0460b56a10fe87713093d13c2b7226″,
“table”:”cdctest”
}

基于MySQL的高可用准实时的数据同步方案

       总结

以上就是CDC工具的设计思路。通过该工具,MySQL数据同步问题可以很方便的解决。

原文地址:https://www.cnblogs.com/syncnavigator/p/10189111.html