专栏首页微观技术如何通过Binlog来实现不同系统间数据同步

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

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

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

本文分享自微信公众号 - 微观技术(weiguanjishu),作者:TomGE

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 如何设计一个高性能的秒杀系统

    秒杀系统要如何架构,在做技术方案时要注意哪些问题,搞了个秒杀专辑,专门收集秒杀系列文章。

    用户7676729
  • StampedLock知识点梳理

    接下来几篇文章会对JUC并发包里面的锁工具类做下梳理,如:ReentrantLock、

    用户7676729
  • DDD是如何解决复杂业务扩展问题?

    业务初期,功能比较简单,CRUD基本可以满足。但随着系统的不断演化,业务系统越来越复杂,各模块间有着千丝万缕的关系,如何提升其扩展性,避免牵一发而动全身,是我们...

    用户7676729
  • Monja用大数据分析为机构投资者量体裁衣

    文|英途途友玉器贷副总裁王金伟 2015年8月,英途邀请平安、宜信、玖富、景林等互联网金融领先公司到硅谷进行考察。一周时间,对话了近20家网贷、众筹、金融服务...

    小莹莹
  • 响铃:救市之作三星S6 edge+能否完成使命?

    大概没有谁比三星更需要一些好消息来振奋市场了。 智能手机市场经过几年的疯狂发展之后现在仿佛进入了一个瓶颈时期。一方面是竞争激烈加剧,另一方面是营销同质化。201...

    曾响铃
  • 透过 Top 500 美拍短视频看 AV1 性能

    AV1 以其出色的压缩性能,无疑是自 2017 年以来备受关注的新生代视频编码标准。业界也相继对 AV1 进行了一些评测工作,如 Facebook、Netfli...

    LiveVideoStack
  • Python的枚举类型

    ZONGLYN
  • 数据库相关中间件介绍

    https://www.cnblogs.com/grefr/p/6087942.html#top

    二狗不要跑
  • 数据库中间件

    作者:[美]威廉·肯尼迪(William Kennedy)布赖恩·克特森(Brian

    李海彬
  • 存储成本降低80%,有赞数据中台成本治理怎么做的?

    从整体的资源角度看,有赞数据中台机器数量在 1500 台左右,其中大部分是物理机,也有一部分是虚拟机,同时有 100 个左右的应用、4 万个核,数据规模在 15...

    腾小云

扫码关注云+社区

领取腾讯云代金券