跨系统实时同步数据解决方案

news2024/9/22 0:05:04

数据量太大,单存储节点存不下,就只能把数据分片存储。

数据分片后,对数据的查询就没那么自由。如订单表按用户ID作为Sharding Key,就只能按用户维度查询。我是商家,我想查我店铺的订单,做不到。(强行查也不是不行,在所有分片上都查一遍,再把结果聚合,又慢又麻烦,实际意义不大)

这样的需求,普遍空间换时间。再存一份订单数据到商家订单库,然后以店铺ID作为Sharding Key分片,专门供商家查询订单。同样一份商品数据,如按关键字搜索,放在ES比MySQL快几个数量级。因为数据组织方式、物理存储结构和查询方式,对查询性能影响巨大,且海量数据还会指数级地放大这性能差距。

海量数据处理都是根据业务对数据查询需求,反过来确定选择数据库、如何组织数据结构、如何分片数据,才能达到最优查询性能。一份订单数据,除了在订单库保存一份用于在线交易,还会在各种数据库中,以各种各样的组织方式存储,用于满足不同业务系统的查询需求。

如何能够做到让这么多份数据实时地保持同步?

分布式事务可解决数据一致性。可用本地消息表,把一份数据实时同步给另外两、三个数据库,这样还可以接受,太多也不行,并且对在线交易业务还有侵入性,所以分布式事务是解决不了这问题。

如何把订单数据实时、准确无误地同步到这么多异构数据。

1 Binlog+MQ=实时数据同步系统

早期大数据刚兴起,大多系统还做不到异构数据库实时同步,普遍使用ETL工具定时同步数据,在T+1时刻同步上个周期的数据,然后再做后续计算和分析。定时ETL对于一些需要实时查询数据的业务需求无能为力。所以,这种定时同步的方式,基本上都被实时同步的方式给取代。

怎么做大数据量、多个异构数据库的实时同步?利用Canal把自己伪装成一个MySQL的从库,从MySQL实时接收Binlog然后写入Redis中。把这个方法稍微改进,就用来做异构数据库的同步。

为了能够支撑下游众多的数据库,从Canal出来的Binlog数据不能直接去写下游那么多数据库:

  • 写不过来
  • 对每个下游数据库,它可能还有一些数据转换和过滤的工作要做。要增加一个MQ解耦上下游

img

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

2 如何保证数据同步的实时性

这方法看起来不难,但易出现性能问题。有些接收Binlog消息的下游业务,数据实时性要求高,不容忍太高的同步时延。比如说,每个电商在大促的时候,都会有一个大屏幕,实时显示现有多少笔交易,交易额。

大促时,数据量大、并发高、数据库中的数据变动频繁,同步的Binlog流量也大。为保证同步实时性,整个数据同步链条上的任何一个环节,处理速度都得跟得上。

源头的订单库,若它出现繁忙,对业务的影响就不只是大屏延迟,那就影响到用户下单,这问题是数据库本身要解决,我们不考虑。

Canal和MQ这两个环节,由于没业务逻辑,性能都好。一般易成为性能瓶颈的就是消费MQ的同步程序,因为有一些业务逻辑,且若下游数据库写性能跟不上,表象也是这个同步程序处理性能上不来,消息积压在MQ。

能不能多加一些同步程序的实例数或增加线程数,通过增加并发提升处理能力?这的并发数,还真不是随便说扩容就可以就扩容。MySQL主从同步Binlog是个单线程同步过程。从库执行Binlog须按序执行,才能保证数据和主库是一样。为确保数据一致性,Binlog顺序很重要,绝对不能乱序。 严格来说,对每个MySQL实例,整个处理链条都必须是单线程串行执行,MQ主题也设置为只有1个分区(队列),才能保证数据同步过程中的Binlog严格有序,写到目标数据库的数据才正确。

那单线程处理速度上不去,消息越积压越多,不无解?办法还是有,但得和业务结合。我们并不需要对订单库所有更新操作都严格有序执行,如A、B两个订单号不同的订单,这两个订单谁先更新谁后更新不影响数据一致性。但同一订单,若更新的Binlog执行顺序错,那同步出来的订单数据真错。即只要保证每个订单的更新操作日志的顺序别乱。这种一致性为因果一致性(Causal Consistency),有因果关系的数据之间严格保证顺序,没有因果关系的数据之间的顺序无所谓。就可并行数据同步。

先根据下游同步程序的消费能力,计算出要多少并发

然后设置MQ中主题的分区(队列)数量和并发数一致。因为MQ可保证同一分区内,消息不乱序,所以把具有因果关系的Binlog都放到相同分区,就可保证同步数据因果一致性。对应订单库,相同订单号的Binlog发到同一分区。

这和数据库分片有点像?分片算法就可复用,如最简单的哈希算法,Binlog中订单号除以MQ分区总数,余数就是这条Binlog消息发往分区号。

Canal自带分区策略就支持按照指定Key,把Binlog哈希到下游的MQ中去,具体的配置Canal接入MQ的文档。

3 总结

对于海量数据,必须要按照查询方式选择数据库类型和数据的组织方式,才能达到理想的查询性能。这就需要把同一份数据,按照不同的业务需求,以不同的组织方式存放到各种异构数据库中。因为数据的来源大多都是在线交易系统的MySQL数据库,所以我们可以利用MySQL的Binlog来实现异构数据库之间的实时数据同步。

为了能够支撑众多下游数据库实时同步的需求,可通过MQ解耦上下游,Binlog先发送到MQ中,下游各业务方可以消费MQ中的消息再写入各自DB。

若下游处理能力不满足要求,可增加MQ中的分区数量实现并发同步,但要结合同步的业务数据特点,把具有因果关系的数据哈希到相同分区,避免因并发乱序而出现数据同步错误的问题。

FAQ

这种数据同步架构下,若下游某同步程序或数据库问题,需要把Binlog回退到某时间点重新同步,怎么解决?

对象存储并不是基于日志来进行主从复制的。假设我们的对象存储是一主二从三个副本,采用半同步方式复制数据,也就是主副本和任意一个从副本更新成功后,就给客户端返回成功响应。主副本所在节点宕机之后,这两个从副本中,至少有一个副本上的数据是和宕机的主副本上一样的,我们需要找到这个副本作为新的主副本,才能保证宕机不丢数据。但是没有了日志,如果这两个从副本上的数据不一样,我们如何确定哪个上面的数据是和主副本一样新呢?

一般基于版本号。在Leader上,KEY每更新一次,KEY的版本号就加1,版本号作为KV的一个属性,一并复制到从节点上,通过比较版本号就可以知道哪个节点上的数据最新。

比较时间戳的方式理论可行,但实际难实现,因为它要求集群上的每个节点的时钟都必须时刻保持同步,这个要求往往非常难达到。

如果预估了分区(队列)数量之后 随着业务数据的增长 需要增加分区 提高并发 怎么去做扩容?
因为统一笔订单需要打到同一个分区上

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

mq 可以有多个 sharding key 是订单号,这样同一个订单号就可以保证到同一个mq里边去,保证顺序,但是canal不还是必须只有一个 不会成为瓶颈?

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

都用mq了还能是实时同步数据嘛?一般使用MQ,也可以做到秒级延迟。

今把binlog回退到某个时间点开始重新同步,这个需要mq消费端的消费进度支持重置,重置到过去的某一个消费进度就可以。本身row格式的binlog就是幂等的,mq也要求消费者必须具备幂等性。所以,自然就支持重置。

如果应用跨云(AWS和阿里)部署,并且使用的数据库不是MySQL而是PG,有什么好方法可以实时这种跨云数据同步?PG也有WAL,和MySQL的Binlog是类似的。参考一下这个开源项目:https://github.com/debezium/debezium

下游的某个同步程序或数据库出了问题,可以抛出异常不确认消息,这样,等数据库好了,再次进行消费,不过这样性能会差点,数据也有延迟。如果不想影响多个系统共用的MQ,可以把数据再发送到某个业务系统单独的MQ中去,后续自己单独慢慢消费。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/133565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ubuntu18.04下mysql数据库C语言API操作总结

通过C/C去操作数据库需要调用mysql客户端api,常用api和调用举例见后面。 目录 一.常用api 1.环境初始化 2.连接 mysql 的服务器 3.增删改查操作 4.事务处理 5.处理查询数据集合 6.释放资源,关闭连接 7.字符集相关 8.获取错误信息 二.api调用举…

Linux杂谈之sudo

一 sudo配置文件/etc/sudoers介绍 ① 什么是sudo 1) sudo 的英文全称是 super user do,即以超级用户root 用户的方式执行命令2) /etc/sudoers 是一个文本文件,只有root用户有该命令的执行权限 1) 允许普通用户以特权用户的权限去执行某些特权命令,访问和使用本…

优秀国土空间规划设计网络评选投票投票怎么进行小程序免费使用

如果通过一个小程序免费制作一个微信投票活动呢?文章详细讲解如何利用一款免费好用的微信小程序“活动星投票”小程序来制作投票活动,无需注册即可免费制作,非常的方便快捷,可以实现视频投票、分组投票、隐藏选手票数、导出投票数…

【Linux】进程概念(下)

​🌠 作者:阿亮joy. 🎆专栏:《学会Linux》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉进程状态&…

手把手教你用Python和OpenCV搭建一个半自动标注工具(详细步骤 + 源码)

导 读 本文将手把手教你用Python和OpenCV搭建一个半自动标注工具(包含详细步骤 源码)。 背景介绍 样本标注是深度学习项目中最关键的部分,甚至在模型学习效果上起决定性作用。但是,标注工作往往非常繁琐且耗时。一种解决方案是…

【苹果家庭群发推】创作AppleScript脚本来控制MacOS附有的iMessage客户端停止考据,近似于组iMessage

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

ENVI_IDL:如何对文件名的日期进行格式化输出?

目录 00 前言 01 第一步,使用file_basename()函数路径中的获取文件名 02 第二步,使用strmid()函数获取文件名的日期 03 第三步,将获取的日期进行类型转换 04 第四步,将日期进行整理 05 第五步,进行格式化输出 …

BiSeNetv2:语义分割经典方法BiSeNet的升级版本

分享IJCV2021上发表的一篇文章BiSeNetv2,这是BiSeNet的升级版本。开源代码地址:https://github.com/open-mmlab/mmsegmentation/tree/master/configs/bisenetv2 1.动机 语义分割是指为每个像素分配一个标签,它广泛用于场景理解、自动驾驶、人…

uniapp中app真机模拟以及小程序编译后css样式异常失效问题原因及解决方案

前言 最近写使用uniapp写app,开发的时候写样式都是使用浏览器h5进行调试一切正常,但是最后进行手机真机调试的时候css样式出现了异常,本文归纳常见的问题 比如在h5页面显示正常: 但是在真机调试app的实现则显示: H5正…

【PyTorch深度学习实践】02_梯度下降

文章目录梯度下降1.梯度下降算法实现代码2.随机梯度下降实现代码3.小批量随机梯度下降梯度下降 1.梯度下降算法 之前可以使用穷举的方法逐个测试找使损失函数最小的点,但当数据过多时,维度过高,会使穷举变得非常困难,因此需要优…

K8s 数据管理

目录前言一、Volume1.1 emptyDir1.1.1 基本概念1.1.2 应用案例1.2 hostPath1.2.1 基本概念1.2.2 应用案例1.3 外部 Storage Provider二、Persistent Volume2.1 基本概念2.1.1 PersistentVolume2.1.2 PersistentVolumeClaim2.2 NFS PersistentVolume前言 与 Docker 类似&#x…

QML教程(一)基础语法

目录 一、导入 二、对象声明 三、对象属性 1.声明对象属性 2.信号属性 3.方法属性 4.附加属性略 5.枚举属性 6.对象属性赋值 四、自定义对象 一、导入 模块导入 语法&#xff1a; import <ModuleIdentifier> [<Version.Number>] [as <Qualifier>…

面向对象设计原则概述

面向对象设计原则概述 软件的可维护性和可复用性 软件工程和建模大师Peter coad认为&#xff0c;一个好的系统设计与应该具备如下三个性质 可扩展性 灵活性 可插入性 软件的可维护性和可复用性 软件的复用和重用拥有众多优点&#xff0c;如可以提高软件的开发效率&#xf…

Educational Codeforces Round 92 (Rated for Div. 2) B. Array Walk

翻译&#xff1a; 给定一个数组&#x1d44e;1&#xff0c;&#x1d44e;2&#xff0c;…&#xff0c;&#x1d44e;&#x1d45b;&#xff0c;由&#x1d45b;个正整数组成。 最初&#xff0c;您位于索引1&#xff0c;分数等于&#x1d44e;1。你可以执行两种动作: 向右移动…

CDN

CDN——Content Delivery Network&#xff0c;内容分发网络。 具体来说&#xff0c;CDN就是采用更多的缓存服务器&#xff08;CDN边缘节点&#xff09;&#xff0c;布放在用户访问相对集中的地区或网络中。当用户访问网站时&#xff0c;利用全局负载技术&#xff0c;将用户的访…

【CSP】邻域均值

邻域均值 邻域均值 题意比较好理解&#xff0c;就是算一些数字。如果采用暴力方法的话&#xff0c;就是用一个边长为 2∗r12*r12∗r1 的正方形框框住大矩阵&#xff0c;然后遍历这个框&#xff0c;求出其平均值&#xff0c;然后移动正方形框&#xff0c;直到大矩阵内所有像…

【免费开放源码】审批类小程序项目实战(预约审批端)

第一节&#xff1a;什么构成了微信小程序、创建一个自己的小程序 第二节&#xff1a;微信开发者工具使用教程 第三节&#xff1a;深入了解并掌握小程序核心组件 第四节&#xff1a;初始化云函数和数据库 第五节&#xff1a;云数据库的增删改查 第六节&#xff1a;项目大纲以及制…

6.5 特殊用途语言特性

文章目录默认实参使用默认实参调用函数默认实参声明默认实参初始值内联函数和constexpr函数内联函数constexpr 函数把内联函数和constexpr函数声明在头文件内调试帮助assert预处理宏NDEBUG预处理变量默认实参 某些函数有这样一种形参,在函数的很多次调用中它们都被赋予一个相同…

电子游戏销售之缺失值检测与处理

电子游戏销售之缺失值检测与处理 文章目录电子游戏销售之缺失值检测与处理0、写在前面1、数据缺失值预处理1.1 表的形状1.2 原始数据每个特征缺失和非缺失的数目1.3 每个特征缺失的率1.4 处理后各特征缺失值的数目1.5 删除缺失值后的数据展示2、替换法处理缺失值2.1 替换法2.2 …

1.Springboot配置细节

一、参考资料 13-SpringBoot配置-项目外部配置加载顺序_哔哩哔哩_bilibili 二、配置 2.1 配置文件 注意变量后面是:&#xff0c;而不是等号 2.2 读取配置文件 2.2.1 Value 比如配置文件application.properities中定义了一个name&#xff0c;其值为abc。 代码里面只需按照如…