RocketMQ 主从复制原理深度解析

提到主从复制,我们可能立马会联想到 MySQL 的主从复制。

MySQL 主从复制是 MySQL 高可用机制之一,数据可以从数据库服务器主节点复制到一个或多个从节点。

这篇文章,我们聊聊 RocketMQ 的主从复制,希望你读完之后,能够理解主从复制的精髓。

1 同步与异步

在 RocketMQ 的集群模式中,Broker 分为 Master 与 Slave,一个 Master 可以对应多个 Slave,但是一个 Slave 只能对应一个 Master。

每个 Broker 与 Name Server 集群中的所有节点建立长连接,定时注册 Topic 信息到所有 Name Server。

Master 节点负责接收客户端的写入请求,并将消息持久化到磁盘上。而 Slave 节点则负责从 Master 节点复制消息数据,并保持与 Master 节点的同步。

  • 同步复制

生产者发送消息后,Master 接收到存储消息请求,将消息数据同步给 Slave 后,才将存储结果返回给生产者。同步复制模式下,发送消息会有一定延迟,系统吞吐量也会降低。

  • 异步复制

生产者发送消息后,Master 接收到存储消息请求,将消息存储后,直接将存储结果返回给生产者。 Master 和 Slave 再通过异步的方式同步数据,这种复制模式具有较小的延迟,可以实现比较高的吞吐量。

若 Master 出现故障,有些数据可能未写入 Slave ,未同步的数据可能丢失。

复制流程分为两个部分:元数据复制消息数据复制

  • 主从服务器同步主题,消费者进度,延迟消费进度,消费者配置数据
  • 主从服务器同步消息数据

2 元数据复制

Slave Broker 定时任务每隔 10 秒会同步元数据,包括主题消费进度延迟消费进度消费者配置

同步主题时,Slave Broker 向 Master Broker 发送 RPC 请求,返回数据后,首先加入本地缓存里,然后持久化到本地。

3 消息数据复制

下图是 Master 和 Slave 消息数据同步的流程图。

1、Master 启动后监听指定端口;

Master 启动后创建 AcceptSocketService 服务,用来创建客户端到服务端的 TCP 链接。

RocketMQ 抽象了链接对象 HAConnection , HAConnection 会启动两个线程,分别用于读服务和写服务:

  • 读服务:处理 Slave 发送的请求
  • 写服务:用于向 Slave 传输数据

2、Slave 启动后,尝试连接 Master ,建立 TCP 连接;

HAClient 是客户端 Slave 的核心类 ,负责和 Master 创建连接和数据交互。

客户端在启动后,首先尝试连接 Master , 查询当前消息存储中最大的物理偏移量 ,并存储在变量 currentReportedOffset 里。

3、Slave 判定拉取间隔是否大于 5 秒,则向 Master 汇报已拉取消息偏移量;

上报进度的数据格式是一个 Long 类型的 Offset , 8 个字节,非常简洁 。

发送到 Socket 缓冲区后,修改最后一次的写时间 lastWriteTimestamp 。

4、Master 解析请求偏移量,从消息文件中检索该偏移量后的所有消息;

当 Slave 上报数据到 Master 时,触发 SelectionKey.OP_READ 事件,Master 将请求交由 ReadSocketService 服务处理:

当 Slave Broker 传递了自身 commitlog 的 maxPhyOffset 时,Master 会马上中断 selector.select(1000) ,执行 processReadEvent 方法。

processReadEvent 方法的核心逻辑是设置 Slave 的当前进度 offset ,然后通知复制线程当前的复制进度。

写服务 WriteSocketService 从消息文件中检索该偏移量后的所有消息,并将消息数据发送给 Slave。

5、Slave 接收到数据,将消息数据 append 到消息文件 commitlog 里 。

首先 HAClient 类中调用 dispatchReadRequest 方法 , 解析出消息数据 ;

然后将消息数据 append 到本地的消息存储。

4 同步的实现

从数据复制流程图,我们发觉数据复制本身就是一个异步执行的,但是同步是如何实现的呢?

Master Broker 接收到写入消息的请求后 ,调用 Commitlog 的 aysncPutMessage 方法写入消息。

这段代码中,当 commitLog 执行完 appendMessage 后, 需要执行刷盘任务同步复制两个任务。

但这两个任务并不是同步执行,而是异步的方式,使用了 CompletableFuture 这个异步神器

当 HAConnection 读服务接收到 Slave 的进度反馈,发现消息数据复制成功,则唤醒 future 。

最后 Broker 组装响应命令 ,并将响应命令返回给客户端。

5 总结

1、主从复制包含元数据复制和消息数据复制两个部分;

2、元数据复制

​ Slave Broker 定时任务每隔 10 秒向 Master Broker 发送 RPC 请求,将元数据同步到缓存后,然后持久化到磁盘里;

3、消息数据复制

  • Master 启动监听指定端口
  • Slave 启动 HaClient 服务,和 Master 创建 TCP 链接
  • Slave 向 Master 上报存储进度
  • Master 接收进度,消息文件中检索该偏移量后的所有消息,并传输给 Slave
  • Slave 接收到数据后,将消息数据 append 到本地的消息存储。

4、同步的实现

​ 当 commitLog 执行完 appendMessage 后, 需要执行刷盘任务同步复制两个任务,这里用到了 CompletableFuture 这个异步神器。

​ 当 HAConnection 读服务接收到 Slave 的进度反馈,发现消息数据复制成功,则唤醒 future 。最后 Broker 组装响应命令 ,并将响应命令 返回给客户端 。

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

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

相关文章

文献解读-群体基因组第一期|《对BMI的影响:探究BMI的基因型-环境效应》

关键词:应用遗传流行病学;群体测序;群体基因组;基因组变异检测; 文献简介 标题(英文):The Impact of ACEs on BMI: An Investigation of the Genotype-Environment Effects of BMI标…

knex与sequelize 以及断点工具使用

knex 使用 SQL Query Builder for Javascript | Knex.js 首先下载 npm install knex 使用 const knex require(knex)({client: mysql,connection: {host: localhost, // 地址user: root, // 账号password: 123456, // 密码database: user // 数据库}});/*** kn…

React-组件基础使用

组件是什么 概念:一个组件就是用户界面的一部分,它可以有自己的逻辑和外观,组件之间可以互相嵌套,也可以复用多次 组件化开发可以让开发者像搭积木一样构建一个完整的庞大的应用 React组件 在React中,一个组件就是首…

云动态摘要 2024-05-24

给您带来云厂商的最新动态,最新产品资讯和最新优惠更新。 最新优惠与活动 [免费试用]大模型知识引擎体验招募 腾讯云 2024-05-21 大模型知识引擎产品全新上线,为回馈新老客户,50万token免费送,开通服务即领取! 云服…

git教程(IDEA + 命令行)

首先假设你已经安装 git 且 已经初始化完成: // 初始化git config --global user.name "你的用户名" git config --global user.email "你的邮箱"在当前文件夹下创建一个仓库,且该文件夹下会有多个项目 首先在当前文件夹下新建git…

微信小程序毕业设计-校园综合服务系统项目开发实战(附源码+论文)

大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:微信小程序毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计…

VSCode开发Python-Django入门

一、安装配置Python环境及配置Python环境变量 1、python安装包安装后,需要注意pip.exe和pip3.exe的安装; 2、环境变量需要配置两个目录; 3、验证python是否安装成功 通过cmd命令执行:python --version 查看python版本&#xff…

高中生是否需要上电子阅览室

高中生是否需要上电子阅览室,取决于学生的学习需求和个人喜好。以下是一些考虑因素: 1. 便利性:电子阅览室通常提供电脑设备和网络连接,方便学生在线获取学习资源。对于家中没有电脑或者网络不稳定的学生,上电子阅览室…

实战

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 实战一:模拟支付宝蚂蚁森林的能量产生过程 支付宝的蚂蚁森林通过日常的走步、生活缴费、线下支付、网络购票、共享单车等低碳、环保行为…

java函数编程-黑马学习笔记

第一章 01合格的函数 函数就是一个规则 合格的函数就是只要你输入相同,无论多少次调用,不论什么时间调用,输出是相同的。 函数可以引用外部的数据,但是需要去保证外部的数据不可变 static关键字修饰的静态方法本质上和函数没…

XDebug配置几件教程,phpstorm实现http请求断点调试

写这篇的文章的初衷:网络上配置XDebug的文章有很多,XDebug也有官方的文档, PhpStorm也有官方的文档,为什么还要写那? 相信不少人,都有一种感觉,虽然教程很多,但是按教程走一遍,自己的确不能正常调试。 问题出在下面几个方面: 1. 对调试过程中,没有一定的认识,因此…

HBase分布式数据库入门到精通

文章目录 HBase分布式数据库入门到精通 一、简单介绍 二、HBase数据模型 三、HBase的架构 四、HBase写操作流程 五、HBase读操作流程 六、HBase minor小合并和major大合并 七、HBase目标表meta表 八、HBase特点 九、HBase的使用场景 HBase分布式数据库入门到精通 一、…

没开玩笑!高速信号不能参考电源网络这条规则,其实很难做到

高速先生成员--黄刚 看到这篇文章的题目,我相信大家心里都呈现出了这么一个场景:高速信号线在L20层,我只要把L19和L21层都铺上完整的地平面,这不就满足了高速信号线不能参考电源平面这条规则了吗?这难道很难做到吗&…

鸿蒙大厂目前政策变现沉淀思考

鸿蒙引擎定制优化 鸿蒙端hotfix: 技术栈太大了,但是鸿蒙需要学习什么呢? 什么最有价值? 这就是接下来需要表达下我的观点: 1、APP开发 2、应用市场技术专员 【游戏、电商重型APP性能的处理 SmartPerf、构建自己的工…

JVM、JRE 和 JDK 的区别,及如何解决学习中可能会遇到的问题

在学习Java编程的过程中,理解JVM、JRE和JDK之间的区别是非常重要的。它们是Java开发和运行环境的核心组件,各自扮演不同的角色。 一、JVM(Java Virtual Machine) 定义 JVM(Java虚拟机)是一个虚拟化的计算…

EE trade:如何理解做空黄金

理解做空黄金,其实就是理解卖空操作在黄金市场中的应用。卖空,或称为做空,是指投资者预测某资产(在这个例子中是黄金)的价格会下跌,因此采取的一种投资策略。 下面简要说明做空黄金的过程和相关概念: 借入黄金: 首先…

Android 生成正式版密钥库 KeyStore

步骤1:打开生成正式版密钥库设置 点击 Build 菜单,选择 Generate Signed App Bundle or APK: 这是打开后的样子: 步骤2:选择 APK Android App Bundle 是用于上架 Google Play 商店的。 正常情况下选择 APK。 选择…

提升(或降低)插入的内容的位置:\raisebox

\raisebox 是 LaTeX 中的一个命令&#xff0c;用于提升&#xff08;或降低&#xff09;插入的内容&#xff08;如文本、图像等&#xff09;的位置。该命令可以用于调整垂直位置&#xff0c;使内容相对于周围内容上下移动。 语法如下&#xff1a; \raisebox{<distance>}…

探秘网页内容提取:教你定位特定标签

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、定位带有ID属性的第二个标签 三、定位具有特定属性值的标签 四、提取含有特…

分类内按规则拆分一行变多行

Excel的A列是分类列&#xff0c;B列是由">"连接起来的多个字符串&#xff0c;可以看成是合并后的明细&#xff1a; AB1IDRule: Condition2470210642217Test3470251569449Doors & Hardware > Door Jambs> 119mm4470251602217Bathroom > Stone Tops &…