1 同步与异步
在 rocketmq 的集群模式中,broker 分为 master 与 slave,一个 master 可以对应多个 slave,但是一个 slave 只能对应一个 master。
每个 broker 与 name server 集群中的所有节点建立长连接,定时注册 topic 信息到所有 name server。
master 节点负责接收客户端的写入请求,并将消息持久化到磁盘上。而 slave 节点则负责从 master 节点复制消息数据,并保持与 master 节点的同步。
1、同步复制
每个 master 配置一个 slave ,有多对 master-slave ,ha 采用同步双写方式,即只有主备都写成功,才向应用返回成功。
这种模式的优缺点如下:
优点:数据与服务都无单点故障,master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高;
缺点:性能比异步复制模式略低(大约低10%左右),发送单个消息的 rt 会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。
2、异步复制
每个 master 配置一个 slave ,有多对 master-slave ,ha 采用异步复制方式,主备有短暂消息延迟(毫秒级),这种模式的优缺点如下:
优点:即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时master宕机后,消费者仍然可以从slave消费,而且此过程对应用透明,不需要人工干预,性能同多 master 模式几乎一样;
缺点:master 宕机,磁盘损坏情况下会丢失少量消息 。
复制流程分为两个部分:元数据复制和消息数据复制。
主从服务器同步主题,消费者进度,延迟消费进度,消费者配置数据
主从服务器同步消息数据
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 向 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 总结
rocketmq 主从复制的实现思路非常简洁,slave 启动一个线程,不断从 master 拉取 commit log 中的数据,然后在异步 build 出 consume queue 数据结构。
核心要点如下:
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 组装响应命令 ,并将响应命令返回给客户端 。
关于S-FACTORY EXPO 2019赋能智慧产业的分析和介绍
基于DSP与CPLD设计智能变电站电网的IED
寒武纪科技陈天石个人简历
双向晶闸管的构造_导电特性与特征
浅谈多电压JTAG链设计实现
聊聊RocketMQ的主从复制
AMD发布锐龙9 4900H与锐龙9 4900HS处理器 均采用8核心16线程设计
DC9021B -评估 SmartMesh® 网络性能的工具
无线充电的终端应用及机遇
三星计划为Bixby提供助力 并有意借此进军机器人等新兴领域
ACR230ELH电力质量分析仪的的设计原理和应用
数控等离子切割机编程入门(等离子数控切割机编程教学)
电容能否离开电极箔?
好的连接器应具备怎样的环境性能?
滴滴或在日本推网络送餐服务,与Uber展开激烈竞争
软件无线电在CDMA接收中的应用
瑞萨电子开发出首款用于汽车实时应用的40nm工艺嵌入式闪存技术
使用 Portainer 进行 Docker 可视化管理
SMT贴片加工中焊锡膏、锡膏、助焊膏的区别与联系
Linux中裸机串口通信的基本方法