后端存储实战课
李玥
美团高级技术专家
44005 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 30 讲
结束语 (1讲)
后端存储实战课
15
15
1.0x
00:00/00:00
登录|注册

19 | 跨系统实时同步数据,分布式事务是唯一的解决方案吗?

MQ分区数量和并发数一致
并行数据同步
消费MQ的同步程序容易成为性能瓶颈
Canal和MQ性能良好
源头订单库繁忙影响业务
使用MQ解耦上下游,下游业务方消费Binlog数据
利用Canal伪装成MySQL的从库,实时接收Binlog并写入Redis
解决方案:空间换时间,存储数据到专门供查询的库
查询受限
解决Binlog回退重新同步的问题
因果一致性
性能问题
使用Binlog和MQ构建实时数据同步系统
分布式事务无法解决实时同步问题
存储多份数据以满足不同业务系统的查询需求
根据业务需求选择数据库类型和数据组织方式
数据组织方式、物理存储结构和查询方式对查询性能的影响
ES vs MySQL
数据分片存储
思考题
保证数据同步的实时性
实时数据同步问题
大厂对海量数据处理的原则
数据组织方式对查询性能的影响
数据量过大时的存储问题
数据同步架构

该思维导图由 AI 生成,仅供参考

你好,我是李玥。
我们在《15 | MySQL 存储海量数据的最后一招:分库分表》这节课中讲过,数据量太大的时候,单个存储节点存不下,那就只能把数据分片存储。
数据分片之后,我们对数据的查询就没那么自由了。比如订单表如果按照用户 ID 作为 Sharding Key 来分片,那就只能按照用户维度来查询。如果我是一个商家,我想查我店铺的订单,对不起,做不到了。(当然,强行查也不是不行,在所有分片上都查一遍,再把结果聚合起来,又慢又麻烦,实际意义不大。)
对于这样的需求,普遍的解决办法是用空间换时间,毕竟现在存储越来越便宜。再存一份订单数据到商家订单库,然后以店铺 ID 作为 Sharding Key 分片,专门供商家查询订单。
另外,之前我们在《06 | 如何用 Elasticsearch 构建商品搜索系统》这节课也讲到过,同样一份商品数据,如果我们是按照关键字搜索,放在 ES 里就比放在 MySQL 快了几个数量级。原因是,数据组织方式、物理存储结构和查询方式,对查询性能的影响是巨大的,而且海量数据还会指数级地放大这个性能差距。
所以,在大厂中,对于海量数据的处理原则,都是根据业务对数据查询的需求,反过来确定选择什么数据库、如何组织数据结构、如何分片数据,这样才能达到最优的查询性能。同样一份订单数据,除了在订单库保存一份用于在线交易以外,还会在各种数据库中,以各种各样的组织方式存储,用于满足不同业务系统的查询需求。像 BAT 这种大厂,它的核心业务数据,存个几十上百份是非常正常的。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

使用Binlog和MQ构建实时数据同步系统是解决大数据处理中重要问题的有效方法。文章首先强调了数据分片存储对数据查询的限制,并强调了根据业务需求选择数据库类型和数据组织方式以达到最优查询性能的重要性。接着详细介绍了利用MySQL的Binlog实现异构数据库之间的实时数据同步,并通过MQ解耦上下游,实现数据的实时同步。此外,文章还探讨了如何保证数据同步的实时性,提出了基于因果一致性的并行数据同步方法。通过介绍实际的技术方案,为读者提供了解决大数据实时同步问题的思路和方法。文章还提出了一个思考题,讨论了在数据同步架构下,如何解决下游同步程序或数据库出现问题需要回退Binlog并重新同步的情况。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《后端存储实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(26)

  • 最新
  • 精选
  • 李玥
    置顶
    Hi,我是李玥。 这里回顾一下上节课的思考题: 对象存储并不是基于日志来进行主从复制的。假设我们的对象存储是一主二从三个副本,采用半同步方式复制数据,也就是主副本和任意一个从副本更新成功后,就给客户端返回成功响应。主副本所在节点宕机之后,这两个从副本中,至少有一个副本上的数据是和宕机的主副本上一样的,我们需要找到这个副本作为新的主副本,才能保证宕机不丢数据。但是没有了日志,如果这两个从副本上的数据不一样,我们如何确定哪个上面的数据是和主副本一样新呢? 这个问题有些同学已经在留言区给出了答案,一般都是基于版本号来解决,在Leader上,KEY每更新一次,KEY的版本号就加1,版本号作为KV的一个属性,一并复制到从节点上,通过比较版本号就可以知道哪个节点上的数据是最新的。 另外,有的同学提出用比较时间戳的方式来解决这个问题。这个方法理论上可行,但实际上非常难实现,因为它要求集群上的每个节点的时钟都必须时刻保持同步,这个要求往往非常难达到。
    2020-04-09
    7
    37
  • 豆腐居士
    如果预估了分区(队列)数量之后 随着业务数据的增长 需要增加分区 提高并发 怎么去做扩容? 因为统一笔订单需要打到同一个分区上

    作者回复: 1. 停掉Canel; 2. 等MQ中所有的消息都消费完了。 3. 扩容MQ分区数,增加消费者实例数量。 4. 重新启动Canel。

    2020-04-09
    10
    39
  • Geek_772139
    今把binlog回退到某个时间点开始重新同步,这个需要mq消费端的消费进度支持重置,重置到过去的某一个消费进度就可以了

    作者回复: 本身row格式的binlog就是幂等的,mq也要求消费者必须具备幂等性。 所以,自然就支持重置。

    2020-05-26
    17
  • Simon
    老师,请问下都用mq了还能是实时同步数据嘛?

    作者回复: 一般使用MQ,也可以做到秒级延迟。

    2020-04-09
    11
  • VincentJiang
    请问老师,如果应用跨云(AWS和阿里)部署,并且使用的数据库不是MySQL而是PG,有什么好方法可以实时这种跨云数据同步?

    作者回复: PG也有WAL,和MySQL的Binlog是类似的。 你可以参考一下这个开源项目:https://github.com/debezium/debezium

    2020-06-09
    10
  • 飞翔
    老师 mq 可以有多个 sharding key 是订单号,这样同一个订单号就可以保证到同一个mq里边去,保证顺序,但是canal不还是必须只有一个 不会成为瓶颈嘛

    作者回复: 一般Canal是不会成为瓶颈的,你想,MySQL的主从同步也是单线程的,正常情况下也都不会有延迟的。

    2020-04-11
    3
    8
  • 饭饭
    非mysql 同步呢,mysqlsever oracle 是否有对应功能或同步工具?

    作者回复: oracle 也有类似的归档日志。

    2020-04-09
  • 木头发芽
    有点像cpu取指令的冒险,如果当前指令后n条指令跟当前指令没有上下文依赖就可以放入指令流水里并行执行力。计算机科学的各种理论真是到处都在用,学好基础是关键
    2020-04-12
    27
  • 此方彼方Francis
    这节课感觉可以和MySQL同步数据到redis那节合起来。
    2020-04-09
    1
    7
  • 陆老师
    越到后面,留言的越少了。下游的某个同步程序或数据库出了问题,可以抛出异常不确认消息,这样,等数据库好了,再次进行消费,不过这样性能会差点,数据也有延迟。如果不想影响多个系统共用的MQ,可以把数据再发送到某个业务系统单独的MQ中去,后续自己单独慢慢消费
    2020-04-24
    6
收起评论
显示
设置
留言
26
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部