【学习笔记】数据一致性分发

为什么要数据分发

微服务中,每个服务都有独立的数据源,这使得数据同步成为难题。

拉模式or推模式?

拉模式存在的问题

  1. 由于网络延迟,拉取的数据不一定是最新的

  2. 如果频繁向另一服务拉取数据,会给服务造成压力,如果拉取频率过低,数据就会同步不及时。

推模式存在的问题

如何保证数据的一致性?或者说如何保证数据分发的事务性?

数据一致性分发

事务消息盒子(事务性发件箱)

本质是利用本地事务的事务性,保证了消息分发的最终一致性。

  1. 在数据库中新开一张发件表(OUTBOX table),用于存放要分发的数据相关信息。

  2. 在往本地表和发件表一起写数据的时候,开启本地事务,如果成功则一起提交,出错则一起回滚。

  3. 实现消息中继器(MessageRelay),定期拉取OUTBOX table中的数据,并发送到对应服务。

  4. 如果成功,则数据分发成功,否则记录重试次数(实现至少发送一次的功能,接收数据的服务可能需要做幂等处理),若重试次数达到阈值,分发失败,需人工干预。

Killbill Common Queue

是对事务性发件箱的开源实现。

上图中灰色框框起来的部分,就是组件对事务性发件箱的核心实现:

  • 事件分发线程(DispatcherThread)会从数据队列(DBQueue)中拿一个事件(Event),并将这个事件写入到事件表中,后续这个事件扔给事件总线(EventBus)处理。

  • 同一节点的事件总线(EventBus)拿到事件分发线程分发的事件,EventBus再将事件分发到对应的Handler,由Handler处理事件。

  • 如果事件处理成功,则标记成功,失败则记录失败次数,累计到阈值标记失败,由人工干预处理

  • 每一个节点事件分发线程都只负责自己节点分发的事件

reaper机制

事件分发线程有多个,假如在运行过程中有事件分发线程挂了,那这个线程中的事件怎么处理呢?

Killbill Common Queue引入了reaper机制:reaper会监控是否有已经写入数据库表但长时间未处理的事件,如果发现了,就讲这个事件收割,后续这个事件将由自己处理。

收割机机制,保证了killbill common queue的高可用性,相当于保证了事务性发件箱中的Message Relay的高可用性。

EventBus(PersistentBus)

EventBus实现了事件性发件箱的MessageRelay功能。

此外,EventBus的机制为事件机制,一开始会在EventBus中注册handler,handler绑定需要处理的事件,当EventBus中收到event时,就会发送给绑定该事件的handler处理。

async-event

是公司的一个组件,使用了hyperf的事件机制,实现了事务性发件箱的功能。

以下为核心功能dispatch实现:

在45-48行中,方法遍历了所有监听器(listener),把监听器名、事件名、事件中的数据存到发件表中。

在try中,调用listener去处理事件,如果处理成功则将发件表中的事件状态标记为完成。

在catch中,如果处理事件出错,就会记录重试次数。

async-event中存在一个定时任务,每十分钟拉取未处理成功的待处理的事件,然后丢给retry方法重试:

retry方法就是将事件进行重试,先反序列化事件,在将事件丢给对应的监听器处理,如果处理完成就标记完成,否则记录重试次数,如果重试次数达到阈值,则标记失败。

CDC-变更数据捕获( Change Data Capture, CDC )

每个数据库在变更数据是都有事务日志或提交日志。启动可以一个服务(Transaction log miner),用来订阅这个日志,当捕获到数据变更时,就将数据变更内容发送给mq(如果异常会重发至成功)。

变更数据捕获常用作于:

  • 数据迁移:常用于数据库备份、容灾等;

  • 数据分发:将一个数据源分发给多个下游,常用于业务解耦、微服务;

  • 数据采集:将分散异构的数据源集成到数据仓库中,消除数据孤岛,便于后续的分析。

相应开源项目:

  • 阿里 Canal:GitHub - alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件

  • Redhat Debezium:GitHub - debezium/debezium: Change data capture for a variety of databases. Please log issues at https://issues.redhat.com/browse/DBZ.

  • Zendesk Maxwell:GitHub - zendesk/maxwell: Maxwell's daemon, a mysql-to-json kafka producer

  • Airnb SpinalTap:GitHub - airbnb/SpinalTap: Change Data Capture (CDC) service

  • FIink -CDC

内部组件实现:https://git.kkgroup.cn/brd/data-transfer-service

下面是cannal的工作原理

MySQL主备复制原理
  • MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events,可以通过 show binlog events 进行查看)

  • MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)

  • MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据

canal 工作原理
  • canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议

  • MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )

  • canal 解析 binary log 对象(原始为 byte 流)

CQRS-命令查询职责分离

一种设计模式,看了很多资料感觉有点高深了,简单来说就是:

  • 命令:CUD,会改变数据的操作

  • 查询:R,不会改变数据

CQRS将命令和查询划分为两个不同的对象,CQRS使用分离的接口将数据查询操作(Queries)和数据修改操作(Commands)分离开来,这也意味着在查询和更新过程中使用的数据模型也是不一样的。这样读和写逻辑就隔离开来了。

mysql的读写分离是在数据库层进行的,而CQRS也可以理解成一种读写分离,但是读写分离操作是在应用层进行的。

内部实现(es同步组件): https://git.kkgroup.cn/brd/elasticsearch-service

在写数据库时,将数据聚合并同步到es中,在查询聚合数据时到es查询。

要思考的问题

  1. 分发过程中要确保一定发送,如果发送失败就会重试。但由于网络抖动等原因,无法判断是否发送成功,会导致消息可能会发送多次。

  2. 由于会存在消息发送多次的情况,消费端就要做好消息去重或幂等机制

  3. 需要考虑是否有顺序性问题。比如两条消息的消费需要具备顺序性,或使用其他方式规避竟态并发带来的困扰。(没遇到过具体情况)

  4. 业务使用时需要理解最终一致性的最终俩个字,设计上需要容忍获取到中间态的数据。(没遇到过具体情况)

参考资料

简书:KillBill框架介绍

CSDN:如何解决微服务的数据一致性分发问题?

博客园:命令查询职责分离模式CQRS 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MVVM 与 MVC区别和应用场景?

MVVM 和 MVC 1. MVC2. MVVM 1. MVC MVC 是 Model View Controller 的缩写 Model:模型层,是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。View:视图层,用户界面渲染逻辑,通常视图…

Redis实战:Redis在Java中的基本使用

本片将介绍 Redis 在 Java 中的基本使用 文章目录 1、使用jedis操作redis1.1、Jedis简介1.2、引入jedis的Maven依赖1.2、获取连接1.3、使用实例 2、对于JedisPooled的使用2.1、使用JedisPooled2.2、关于连接池 3、SpringBoot下使用Redis3.1、引入Maven依赖3.2、配置Redis连接3.…

MDK自动生成带校验带SVN版本号的升级文件

MDK自动生成带校验带SVN版本号的升级文件 获取SVN版本信息 确保SVN安装了命令行工具,默认安装时不会安装命令行工具 编写一个模板头文件 svn_version.temp.h, 版本号格式为 1_0_0_SVN版本号 #ifndef __SVN_VERSION_H #define __SVN_VERSION_H#define SVN_REVISIO…

微信小程序服务通知(订阅消息)定时推送消息功能

首先先说项目需求:向预约参观的用户提前一天晚上8点推送消息。小程序端主要用到的API是我是小程序用到的API。以及服务端用到的API:我是服务端用到的API。 1. 开通订阅消息功能 (1)、 首先需要在小程序管理后台开通订阅消息功能。没开通前如下图所示: …

《机器学习》第5章 神经网络

文章目录 5.1 神经元模型5.2 感知机与多层网络5.3 误差逆传播算法5.4 全局最小与局部最小5.5 其他常见神经网络RBF网络ART网络SOM网络级联相关网络Elman网络Boltzmann机 5.6 深度学习 5.1 神经元模型 神经网络是由具有适应性的简单单元组成的广泛并行互连的网络,它…

网络安全概述——常见网络攻击与网络病毒、密码体制、安全协议等

目录 1、信息安全五大要素 2、常见的网络攻击类型 2-1)网络攻击的分类: 2-2)常见网络攻击: DOS 攻击的分类: 2-3)常见网络攻击的防范措施 3、计算机病毒 3-1)常见病毒的前缀及其简要描述…

13.2 外部DirectX绘制实现

在前一节中我们简单介绍了D3D绘制窗体所具备的基本要素,本节将继续探索外部绘制技术的实现细节,并以此实现一些简单的图形绘制功能,首先外部绘制的核心原理是通过动态创建一个新的窗口并设置该窗口属性为透明无边框状态,通过消息循…

MySQL案例详解 三:MMM高可用架构及其故障切换

1. MMM高可用概述 1.1 简介 MMM(Master-Master replication manager for MvSQL,MySQL主主复制管理器)是一套支持双主故障切换和双主日常管理的脚本程序。 MMM提供了自动和手动两种方式移除一组服务器中复制延迟较高的服务器的虚拟ip&#xf…

Node.js 正在逐渐被淘汰!Bun 1.0 正在改变 JavaScript 的游戏规则

在深入讨论之前,我们需要解释什么是 JavaScript 运行时以及为什么我们应该关心其速度。 想象一下,你用 JavaScript 写了一个故事,需要有人大声读出来。JavaScript 运行时就像是那个友好的叙述者,为你的故事赋予生命!它…

nSoftware IPWorks IoT 2022 Java 22.0.8 Crack

物联网库,使用这个轻量级组件库,可以在任何平台上的应用程序中轻松实现物联网 (IoT) 通信协议。 nSoftware IPWorks IoT 最新的 IPWorks IoT 现已推出!最新版本的 IPWorks IoT 具有现代化和简化的体验,包括 .NET 中的异步和跨平台…

Android+Appium自动化测试环境搭建及实操

1、Appium简介1.1 Appium概念1.2 Appium工作原理 2、Appium Server环境搭建2.1 Java JDK2.1.1 下载JDK2.1.2 运行exe安装JDK,设置安装路径2.1.3 设置环境变量2.1.4 验证安装结果 2.2 Android SDK2.2.1 下载安装Android SDK安装包2.2.2 下载platform-tools&#xff0…

Android Studio展示Activty生命周期

前言 本文章以及之后文章的程序版本使用Android Studio 2022.3.1 Patch 1 版本编辑,使用语言为java,最低支持API 27 Android 8.1,构建工具版本如下: 本文章主要是介绍Activty跳转和删除,以备后续使用,所以就…