zl程序教程

您现在的位置是:首页 >  后端

当前栏目

RocketMQ 之 Broker Server

server rocketmq Broker
2023-09-11 14:21:18 时间

Broker 其主要是负责存储消息和转发消息,是RocketMQ的核心。那现在我们又有如下几个问题:

1、当MQ会收到大量消息时,这时这些消息又是怎么处理的呢?

其实这些消息一般不会马上被消息消费者拿去处理的,而是在本地磁盘存储下来,然后等待消息消费者来获取消息去处理。

2、那对于这海量的数据RocketMQ又是怎么处理的呢?

其实对于这来说我们一般会搭建Broker集群,消息发送者会把消息分散发给不同的Broker机器上,假设你又10w条消息,分散发送给10台机器。这样每台机器接收到的消息可能就只有1000条了。其次每台机器部署RocketMQ进程一般称为Broker进程,其收到消息会把消息存储在自己的本地磁盘。所以RocketMQ的消息存储本质是分布式存储的。

3、当如果但一台Broker机器突然宕机了,那这台机器的消息会全部丢失吗?

RocketMQ 他提供的解决方案是采用主从架构以及多副本模式,这样当Master宕机之后,还可以接着处理Slave副本的数据。那Master Broker 是如何把数据同步给 Slave Broker 的呢?在RocketMQ中采取的是Slave 节点不断向 Master 发送请求拉去消息来进行数据同步。

  • Topic 概念: 表示一类消息的集合,每个主题包含若干条消息,每条消息只能属于一个主题,是RocketMQ进行消息订阅的基本单位。
  • MessageQueue :消息队列存储消息,在创建Topic的时候可以绑定多个MessageQueue

消息存储

在生产者发送消息到Broker上面时,首先其会把消息按照顺序写入到磁盘的一个日志文件( CommintLog) 。这个 CommintLog 由很多磁盘文件组成,每个文件限定1GB,如果一个写满了则会创建一个新的 CommintLog 文件。然后其就会把消息在 CommintLog 中的 offset 偏移量,消息长度、hashCode等数据存入到ConsumerQueue中(每个ConsumerQueue大概可以保存30w条数据,一条数据20个字节,文件大小大概为5.72M)。
在这里插入图片描述

但对于直接把消息顺序写入磁盘文件CommintLog中这显然会影响性能的,所以Broker是基于OS操作系统的 PageCache 、顺序写、OS异步刷盘策略机制来优化的。其接收到消息后会顺序写入到OS PageCache中,然后后续由OS的的一个后台线程间数据刷入到磁盘文件。

  • 同步刷盘:生产者发送一条消息出去之后,Broker收到消息,必须强制把消息刷入到底层的物理磁盘中,才会返回 ack 给生产者。这时生产者才知道消息写入成功。这样可以避免数据的丢失,除非磁盘坏了。
  • 异步刷盘:生产者发送一条消息出去之后,Broker收到消息,当其将消息写入到 OS PageCache 中就返回 ack 给生产者。这时生产者认为消息写入成功,但这时如果Broker宕机则会导致OS PageCache 中的数据丢失。
  • 优缺点:同步刷盘(写入吞吐量下降 、数据不丢失),异步刷盘(高吞吐写入,有丢失数据的风险) 刷盘方式可以通过Broker配置文件里的flushDiskType参数设置,这个参数有两种值:SYNC_FLUSH (同步刷盘)。ASYNC_FLUSH (异步刷盘)。
    在这里插入图片描述

基于DLedge实现的主从模式

为了保证Broker的高可用行,我们可用通过搭建其主从模式,Broker主从主要是基于DLedge来实现的其主要思想如下:
在这里插入图片描述

DLedger 实际上是他自己有一个ComminLog机制,你把数据给他他会写入CommintLog磁盘文件里面去。基于DLedger技术来实现Broker的高可用架构,实际上就是用DLedger替换掉Broker管理的CommintLog由DLedger来管理。

  • DLedger 基于Raft协议选举Leader Broker 流程

Leader Broker 选举流程在 Broker 启动的时候会发起投票只有当票数大于(机器数 + 1)/ 2时,这个Broker才会被选举为Leader Broker节点。 如果每个人的票数都相同,或者都没超过(机器数 + 1)/ 2时这时会认为选举失败,这时每个Broker 都会随机休眠一段时间,先醒来的人会投票给自己,其他人苏醒的人发现自己收到选举票这时就会直接提交给那个人

  • DLedger 基于 Raft 协议进行多副本数据同步

Leader Broker 数据同步分为两阶段:uncomintted 阶段、comintted 阶段。首先Leader Broker 上的DLedger收到一条数据之后,其会标记为 uncominttd 状态,任何通过DLedger Server 组件把uncomintted 发送给Follower Broker 的DLedger Server,但其接收到消息之后会返回一个ack给Leader Server,当Leader Server 接收到超过半数的Follower Broker 返回的ack之后,将会把消息标致为comintted 状态,同时也通知 Follower Broker 把消息状态改为comitted状态