详细解析msyql和消息队列数据一致性问题

news2024/9/28 11:17:23

目录

前言

保持系统数据同步(双写问题)

消息队列消息丢失的问题

总结


前言

在当今互联网飞速发展的时代,随着业务复杂性的不断增加,消息队列作为一种重要的技术手段,越来越多地被应用于各种场景。它们不仅能有效解耦系统各部分之间的联系,还能够平衡流量峰值,提高系统的整体性能。

在本文中,我将重点分析一家医美公司的团队在使用消息队列时的奇葩做法。这家公司的技术团队选择了 Kafka 作为主要的消息队列,但在某些情况下却出现了数据未能成功消费的问题。为了应对这个挑战,他们又引入了 RocketMQ,并通过其延迟机制来弥补之前的不足。然而,这样的做法是否合理?这背后又隐藏着哪些技术思考与团队协作的缺陷?

接下来,我们将深入探讨这家公司的消息队列应用,以及其中的潜在问题与改进方案。

下面是我画的他们业务的一个架构图:

<图一>

在这个架构图中,数据首先从MySQL数据库流入“业务1”,并通过Kafka进行消息传递。然后,数据被传递到“业务2”进行处理。处理完成后,系统会判断是否成功。如果成功,则数据继续存储到MySQL中;如果未成功处理,则会将消息发送到RocketMQ进行重新处理。

这个架构是非常简单,加入了 RocketMQ 就一个诉求就是消息不丢失,真的能做到吗?其实有几个问题,第一个问题系统同步也就是双重写入问题 第二个问题就是加入RocketMQ 和不合理,下面我们逐一讲解。

保持系统数据同步(双写问题)

我们业务系统有两个双写:业务1的1和2。业务2的5和6。图中这样的设计看起来很简单但是有一些严重的问题。

先用一个流程图来说明双写严重的问题:

<图二>

在这个例子中,两个客户同时想要更新项X:

客户端l 想要将值设置为A,客户端2 想要设置为B 。两个客户端首先将新值写入数据库,然后将其写入消息队列中。由于实机不凑巧,这些请求交叉了:数据库首先看到来自客户端1 的写入,将值设置为A,然后看到来自客户端2 的写入,将值设置为B ,因此数据库中的最终值为B 。而消息队列首先看到来自客户端2 的写人,然后才是客户端1 的写人,所以消息队列中的最终值是A。这两个系统将永远不一致,即使目前还没有发生错误。

除非有一些额外的并发监测机制,或者加入版本向量或者加入分布式锁。否则甚至不会注意到并发写入,一个值悄悄覆盖另一个值。

我们可以总结到双重写入的一个问题就是值会可能被覆盖。

还有一个很难发现的问题就是客户端1或者客户端2写入数据库成功了但是写入消息队列失败了,这不是一个并发问题,这是一个容错问题,也会造成两个系统相互不一致的结果,这是致命的。确保数据库和消息队列都成功或者失败是个原子提交问题,需要用到2pc 等分布式事务相关的技术。

这两个问题都是致命的,必须解决,数据库的主从复制给我了启发,不管如何并发,从库总是订阅主库的binglog,保证了数据的一致性。我们发现我们这个例子其实可以看成两个主库的双写问题,有没有一种技术把两个主库的双写问题转成主从机制呢?那么问题不就解决了吗?还真的是有这种方案,就是CDC 技术。于是我的架构就发生了一种变化。

<图三>

CDC 技术是对系统同步的里程碑,他借助了主从的思想,软件开发工程师开始认识到日志的重要性,再也不认为,数据库复制日志的问题被认为是数据库内部实现细节,他们开始尝试解析日志,捕获数据的变化,写入时立即将更改作为一种流来发布,那么业务只需要消费这些数据就可以了。现在很多数据库都提供了CDC解决方法。mysql 在国内用的最多的是canal。前面讲过就是canal作为一个从库似的获取主库的数据,并且她集成了快照技术也就是说会记录位置的偏移量,以便在快照处理完成后,知道哪一点开始应用修改。canal 具体问题,可以参考相关的文档。

消息队列消息丢失的问题

图一我们发现了该团队用了RocketMQ和kafka 就是解决业务2消息丢失的问题,RocketMQ在哪种情况下会用到,我们将详细分析下:

只有一种情况下,就是消费者出现error 或者异常,代码能捕获到这些问题,调用RocketMQ,用它的延迟队列。其实又有集中假设:

  1. 如果消费者出现了代码本身的bug ,应该在测试阶段就应该发现的,或者经过压测,这是代码问题,应该避免的

  2. 第二种情况就是业务二入库失败了,会把消息投递到RocketMQ,用它的延迟队列过段时间数据库可能就好了,就一定能捕获吗,成功写入到RocketMQ吗?

  3. 如果消费者在处理一半业务就突然挂掉了还能写入到RocketMQ吗,消息还是丢失了

经过分析发现只有第二种情况可能,为了一种可能的情况,引入RocketMQ当然是不合适的,是弊端大于利,而且系统更为复杂,不仅要监控kafka 而且也要监控RocketMQ。

那么我们就想kafka 能不能让消息不丢失呢。当然是可以的呀

在消息队列的处理中,常见的情况有以下几种:

零次处理(At-most-once):消息可能丢失,但不会被重复处理。

一次处理(At-least-once):消息一定会被处理,但可能会被处理多次。

精确一次(Exactly-once):确保每条消息只被处理一次。

消息不丢失我们可以用 At-least-once 消息设计模式

kafka 应该从生产者,消费者,还有服务端 去讨论消息不丢失:

生产者来说:

  1. 使用带回调方法的API。我们就知道消息有没有成功

  1. 设置参数 acks=1 (-1,0,1)。-1生产者在发送消息后不等待任何确认,1 领导者(leader)在成功写入消息后发送确认。 -1 所有的副本(包括领导者和跟随者)都必须确认消息已被成功写入。

  1. 设置参数 retries=3。重试次数,如果次数到了还是失败,我们可以写入日志中

  1. 设置参数 retry.backoff.ms=300。每次重试间隔时间

服务端:

replication.factor>1。 (分区副本的个数),至少一个主分区,多个副本节点

Min.insync.replicas>1。 (isr 最少的副本数量)。

Unclean.leader.election.enable = false。 (是否能把非ISR集合中的副本选举为leader 副本)

定义:ISR 是指与当前主分区(Leader)保持同步的所有副本(Replica)。这些副本在数据写入主分区时,能够及时接收到并确认写入的数据。这是重要的,如果选择了非ISR 节点作为leader ,那么就会造成数据丢失。

消费者:

消费者是根据offset 来确定消息的消费位置,可以手动提交offset,就是业务结束的时候

Enable.auto.commit = false (手动提交偏移量)

具体的代码可以参考相关的文档。

得出了最终的架构是这样的。

总结

这篇文章我们详细介绍了cdc 技术,kafka 如何消息不丢失,同时也详细阐述了结构的不合理性以及合理性的架构是如何演变的

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

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

相关文章

ChatGPT-o1用来进行数据分析,对比效果很惊人!

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 在进行数据分析的时候&#xff0c;通常有一个场景&#xff1a;我有一批数据&#xff0c;但是不知道该怎么分析&#xff0c;才能找到写论文的突破口和角度。ChatGPT能不能给我一…

Java项目实战II基于Java+Spring Boot+MySQL的厨艺交流平台设计与实现(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在美食文化…

江协科技STM32学习- P20 实验-TIM编码器接口测速

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

游戏厅计时器ps5计算时间的软件 佳易王电玩计时计费管理系统操作教程

一、前言 游戏厅计时器ps5计算时间的软件 佳易王电玩计时计费管理系统操作教程 软件为绿色免安装版&#xff0c;解压即可使用。 二、软件程序教程 计时的时候&#xff0c;点击 开始计时按钮 开台后可设置定时语音提醒的时间 时间设置好后&#xff0c;点击 开启提醒 即可 三、…

无人机飞手入伍当兵技术优势分析

随着现代战争形态的不断演变&#xff0c;无人机技术在军事领域的应用日益广泛&#xff0c;成为提升军队作战能力的重要手段。对于无人机飞手而言&#xff0c;其专业技能和实战经验在入伍当兵后能够转化为显著的技术优势&#xff0c;为国防事业贡献重要力量。以下是从专业技能优…

“不关心⚠️Warning”的代价:http自动升级https导致免费的存储服务扣费

背景 7 月 12 日的时候我手机突然收到一条短信&#xff1a;显示我在 LeanCloud 平台的账户欠费了。虽然只是欠费 0.01 元&#xff0c;但还是有些疑惑&#xff0c;怎么免费的存储服务突然扣费了&#xff1f; 然而这只是个开始。起初我并没有很在意这扣费的 0.01 元&#xff08;…

阿里发布Qwen2.5:编程与数学的AI新革命!

阿里发布Qwen2.5&#xff1a;编程与数学的AI新革命&#xff01; 阿里发布了Qwen2.5系列模型&#x1f680;&#xff0c;带来编程和数学领域的超强升级&#x1f9b8;‍♂️。多种规格可选&#xff0c;开源模型推动创新&#x1f513;&#xff0c;让AI助手更智能&#xff01;快来体…

一阶低通滤波器Simulink仿真测试

1、低通滤波器(SMART PLC双线性变化和后向差分对比测试 低通滤波器(SMART PLC双线性变换和后向差分对比测试)_后向差分 和 双线性-CSDN博客文章浏览阅读367次。该博客详细探讨了低通滤波器的设计,对比了SMART PLC中的双线性变换和后向差分法。内容包括Tustin变换公式、后向差…

第一批学习大模型的程序员,已经碾压同事了,薪资差距都甩出一条街了...

前言 随着人工智能技术的突飞猛进&#xff0c;AI大模型已成为引领未来的核心技术。从ChatGPT的横空出世到GPT-4o的震撼发布&#xff0c;AI技术正以前所未有的速度改变着我们的生活和工作方式。 在这场AI革命中&#xff0c;企业对AIGC人才的需求正以指数级增长。据《AIGC就业趋…

基于Hive和Hadoop的病例分析系统

本项目是一个基于大数据技术的医疗病历分析系统&#xff0c;旨在为用户提供全面的病历信息和深入的医疗数据分析。系统采用 Hadoop 平台进行大规模数据存储和处理&#xff0c;利用 MapReduce 进行数据分析和处理&#xff0c;通过 Sqoop 实现数据的导入导出&#xff0c;以 Spark…

OpenAi_Moderation审核更新

更新原文档 最新openai-python版本已不可直接用 openai.Moderation.create()

芝法酱学习笔记(0.5)——使用jenkins做自动打包

前言 上节讲了SpringBoot上的打包。但这些过程都是手动的&#xff0c;在实际的开发测试时&#xff0c;自动化的打包部署&#xff0c;可以大大提升团队开发的效率 一、去官网下载 1.1 官网安装命令 对于如何安装的问题&#xff0c;我向来推荐官网 wget -O /usr/share/keyri…

论文阅读:LM-Cocktail: Resilient Tuning of Language Models via Model Merging

论文链接 代码链接 Abstract 预训练的语言模型不断进行微调&#xff0c;以更好地支持下游应用。然而&#xff0c;此操作可能会导致目标领域之外的通用任务的性能显著下降。为了克服这个问题&#xff0c;我们提出了LM Cocktail&#xff0c;它使微调后的模型在总体上保持弹性。…

解决Mac 默认设置 wps不能双面打印的问题

目录 问题描述&#xff1a; 问题解决&#xff1a; 问题描述&#xff1a; 使用mac电脑的时候&#xff0c;发现wps找不到双面打印的按钮&#xff0c;导致使用wps打开的所有文件都不能自动双面打印 问题解决&#xff1a; mac的wps也是有双面打印的选项&#xff0c;只是默认被关…

双指针算法【算法 18】

双指针算法 在算法设计与实现中&#xff0c;双指针算法是一种非常高效且常用的技术&#xff0c;尤其适用于处理数组和字符串相关的问题。通过维护两个指针&#xff08;通常称为“快指针”和“慢指针”&#xff09;&#xff0c;双指针算法能够在对数组或字符串进行单次遍历的同时…

VSCode rust文件中的api点击无法跳转问题

如果配置了vscode的setting.json windows端的话 "settings": { "typescript.tsc.autoDetect": "off","rust-analyzer.linkedProjects": [".\\gui-btn\\Cargo.toml",".\\temp\\Cargo.toml", ],其他端类似 能不…

电脑怎么进行网页限制操作?

1、修改Hosts文件&#xff1a; 打开文件资源管理器&#xff0c;导航至C:\Windows\System32\drivers\etc\目录&#xff08;注意&#xff0c;修改前最好备份原文件&#xff09;。 找到并打开hosts文件&#xff0c;以管理员身份运行文本编辑器进行编辑。 在文件末尾添加一行&am…

基于Springboot投稿和稿件处理系统设计与实现

博主介绍&#xff1a;专注于Java vue .net php phython 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作 ☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找不到哟 我的博客空间发布了1000毕设题目 方便大家学习使用 感兴趣的…

Java | Leetcode Java题解之第441题排列硬币

题目&#xff1a; 题解&#xff1a; class Solution {public int arrangeCoins(int n) {return (int) ((Math.sqrt((long) 8 * n 1) - 1) / 2);} }

【STM32开发环境搭建】-2-安装STM32CubeMX

目录 1 下载STM32CubeMX 2 使用STM32CubeMX 2.1 设置Embedded software Package存放路径 2.2 下载并安装STM32的Embedded software Package 结尾 1 下载STM32CubeMX 注册一个ST的账号&#xff0c;单击STM32CubeMX - STM32Cube初始化代码生成器 - 意法半导体STMicroelectr…