前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何通过Binlog来实现不同系统间数据同步

如何通过Binlog来实现不同系统间数据同步

作者头像
微观技术
发布2020-08-20 15:29:59
1.3K0
发布2020-08-20 15:29:59
举报
文章被收录于专栏:微观技术微观技术

互联网时代除了业务迭代速度快,还有就是数据增速也比较快。单应用、单实例、单数据库的时代早已不复返。现在,作为技术研发,如果参与的项目没有用到分库分表,都不好意说自己做过大项目。

以电商为例, 角色分为买家和卖家,当网站的规模发展到一定的规模后,系统订单采用单表是满足不了用户需求的。分库分表势在必行。由于存在买家、卖家两个维度,所以一个Sharding Key满足不了业务需求。

常规的解决方式是采用空间换时间,毕竟存储的成本越来越低,我们会考虑数据复制,异构化处理。也同步一份数据到卖家的订单库,然后以卖家uid作为 Sharding Key 分片,专门供商家查询订单。

数据异构有两种方式:

1、写入DB订单表时,采用双写模式,买家表创建完后,然后在卖家表也创建一份数据记录,可以采用不用的分表键,写入不同的数据分片中。由于额外增加数据同步的写操作,会导致同步接口RT增大,从而影响整个系统的QPS。

可能有同学立马会说,我们可以采用异步方式,系统启动时初始化一个线程池,把同步业务逻辑封装成任务丢给线程池异步去执行。由于是本地任务,很难监控任务的执行情况,如果不小心赶上发布重启,还会有数据丢失的风险

2、另一种方式可以借助MQ,买家库写完后,发送事务消息,然后接口就可以结束响应。至于卖家库的操作可以消息任务,异步去写入,如果写入失败可以借助消息框架自身的重试机制。

缺点:如果一个业务的数据要异构化处理,就需要对所有的业务动作封装MQ消息体,代码无法做到通用性,跟业务强耦合。

3、有没有更通用的方式,可以通过binlog构建数据实时同步。这里要一个阿里巴巴的开源框架 Canal。

MySQL主备复制原理

  • MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events,可以通过 show binlog events 进行查看)
  • MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)
  • MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据

Canal 将自己伪装成一个 MySQL 从库,从 MySQL 实时接收 Binlog 然后写入数据库表。为了能够支撑下游众多的数据库,从 Canal 出来的 Binlog 数据肯定不能直接去写下游那么多数据库,一是写不过来,二是对于每个下游数据库,它可能还有一些数据转换和过滤的工作要做。所以需要增加一个 MQ 来解耦上下游。

Canal 从 MySQL 收到 Binlog 并解析成结构化数据之后,直接写入到 MQ 的一个订单 Binlog 主题中,然后每一个需要同步订单数据的业务方,都去订阅这个 MQ 中的订单 Binlog 主题,消费解析后的 Binlog 数据。在每个消费者自己的同步程序中,它既可以直接入库,也可以做一些数据转换、过滤或者计算之后再入库,这样就比较灵活了。

注意:由于采用异步消息,数据同步可能会存在一定延迟,一般都是在毫秒级别,不过要注意监控消息的堆积情况,避免一些特殊情况下,消息大量堆积导致数据同步延迟拉大,进而影响到正常业务。

在数据同步的实时方面,有什么可以做的?

我们都知道电商大促期间,系统的并发是很高的,数据库写操作很频繁,同步的binlog流量会比较大,消费MQ消息的同步程序很容易成为性能瓶颈,从而影响到数据同步实时性。

面对这个问题,我们一般会通过多加一些同步程序的实例数,或者增加线程数,通过增加并发来提升处理能力。但是要考虑一个点,MySQL 主从同步 Binlog,是一个单线程的同步过程,原因很简单,为了确保数据一致性,Binlog 的顺序很重要,是绝对不能乱序的。MQ 的topic也必须设置为只有 1 个分区(队列),这样才能保证数据同步过程中的 Binlog 是严格有序的,写到目标数据库的数据才能是正确的。

但是单线程处理速度肯定跟不上,有没有什么好的解决方案?我们可以考虑跟业务结合起来解决。

比如电商的订单库,不同的binlog并发执行受影响的只可能是同一条记录,也就是说同一个订单,如果更新的 Binlog 执行顺序错了,那同步出来的订单数据真的就错了。相反,不同的行记录,错乱的执行顺序并不会影响到数据的一致性。

画外音:有因果关系的数据之间必须要严格地保证顺序,没有因果关系的数据之间的顺序是无所谓的。

基于这个理论,我们要评估下游同步程序的消费能力,计算出并发数。然后设置 MQ 中topic的分区(队列)数量和并发数一致。因为 MQ 是可以保证同一分区内,消息是有序的。所以我们需要把具有因果关系的 Binlog 放到相同的分区中。对应到订单库就是,相同订单号的 Binlog 必须发到同一个分区上。

关于canal的快速使用,可参考下面的文章

https://github.com/alibaba/canal/wiki/Canal-Kafka-RocketMQ-QuickStart

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微观技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档