RocketMq和QMQ

本文主要介绍了RocketMQ和QMQ两款消息中间件的特性。RocketMQ的物理部署结构包括NameServer、Broker、Producer和Consumer,消息存储采用文件系统,强调顺序写入以提高性能。QMQ则针对RocketMQ的消费模式进行了优化,通过引入Pull Log解决负载均衡问题,并采用本地事务表实现分布式事务。两者在持久化方式上都采用异步刷盘和主从复制,但QMQ在负载均衡和事务处理上有独特设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

rocketMq

物理部署结构

在这里插入图片描述

  • name Server 简化版的zookeeper注册中心,可集群部署,但是节点之间无任何信息的同步

  • broker分为master和slave, 一个master可对应多个slave,但是一个slaver只能对应一个master. Master 与 Slave 的对应关系通过指定相同的 BrokerName,不同的 BrokerId 来定义,BrokerId为 0 表示 Master,非 0 表示 Slave。

    master也可以部署多个,每个broker都与Name server集群中的所有节点建立长连接,定期注册Topic信息到name server上.

  • producer 生产者, 于name Server集群中的其中一个(随机选择)节点建立长连接,定期中Name Server中获取对应Topic的路由信息.并向提供对应Topic服务的Master建立长连接,定时向Master发送心跳.

  • Consumer 消费者,同样会与NameServer集群中的其中一个节点(随机选择)建立长连接,定期中Name Server中获取Topic的路由信息.并向提供Topic服务的Mster、slave 建立长连接.且定时向Master 、Slave发送心跳. Consumer既可以从Master订阅消息,也可以从Slave订阅消息,订阅规则由Broker决定.

逻辑部署结构

在这里插入图片描述

  • Producer Group

    用来表示一个发送消息的应用,一个Producer Group下包含多个Producer实例,可以是多台机器,也可以是一台机器的多个进程,躲着一个进程的多个Producer对象.一个Producer Group可以发送多个Topic消息.Producer Group作用如下

    1. 标识一类 Producer

    2. 可以通过运维工具查询这个发送消息应用下有多个 Producer 实例

    3. 发送分布式事务消息时,如果 Producer 中途意外宕机,Broker 会主动回调 Producer Group 内的任意一台机器来确认事务状态。

  • Cousumer Group

    用来表示一组消费消息的应用.一个 Consumer Group 下包含多个 Consumer 实例,可以是多台机器,也可以是多个进程,或者是一个进程的多个 Consumer 对象。

    集群模式一个 Consumer Group 下的多个 Consumer 以均摊方式消费消息,如果设置为广播方式,那么这个 Consumer Group 下的每个实例都消费全量数据。

持久化方式

存储介质

市面上主流的消息队列对于消息的持久化主要有两种方案,一种是关系型数据库DB,一种是文件系统

  • 关系型数据库DB

    Apache下开源的另外一款MQ—ActiveMQ(默认采用的KahaDB做消息存储)可选用JDBC的方式来做消息持久化,通过简单的xml配置信息即可实现JDBC消息存储。由于,普通关系型数据库(如Mysql)在单表数据量达到千万级别的情况下,其IO读写性能往往会出现瓶颈。在可靠性方面,该种方案非常依赖DB,如果一旦DB出现故障,则MQ的消息就无法落盘存储会导致线上故障

  • 文件系统

    目前业界较为常用的几款产品(RocketMQ/Kafka/RabbitMQ)均采用的是消息刷盘至所部署虚拟机/物理机的文件系统来做持久化(刷盘一般可以分为异步刷盘和同步刷盘两种模式)。消息刷盘为消息存储提供了一种高效率、高可靠性和高性能的数据持久化方式。除非部署MQ机器本身或是本地磁盘挂了,否则一般是不会出现无法持久化的故障问题。并且对文件系统进行顺序的写入效率很高.

性能对比:

文件系统> 关系型数据库DB

消息的存储和发送
1. 消息存储

磁盘如果使用得当,磁盘的速度完全可以匹配上网络 的数据传输速度。目前的高性能磁盘,顺序写速度可以达到600MB/s, 超过了一般网卡的传输速度。但是磁盘随机写的速度只有大概100KB/s,和顺序写的性能相差6000倍!因为有如此巨大的速度差别,好的消息队列系统会比普通的消息队列系统速度快多个数量级。RocketMQ的消息用顺序写,保证了消息存储的速度。

2. 消息发送

Linux操作系统分为【用户态】和【内核态】,文件操作、网络操作需要涉及这两种形态的切换,免不了进行数据复制。

一台服务器 把本地磁盘的文件内容发送到客户端,一般分为两个步骤:

  1. read: 读取本地文件到用户态的内存

  2. write: 将读取的内容通过网络发送出去

两个操作,实际进行了四次的数据复制

  1. 从磁盘将数据复制到内核态内存
  2. 从内核态内存将数据复制到用户态内存
  3. 然后从用户态内存复制到网络驱动的内核态内存
  4. 最后从内核态内存复制到网卡中进行传输

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q5siQtHT-1605342872441)(图片/消息队列/image-20201006010820217.png)]

而零拷贝技术可以省去向用户态复制的操作,直接内核态将数据从磁盘读出来之后,直接发送出去,不在向用户态进行复制,这种方式的前提是数据不需要修改,而消息队列的场景一般不需要对消息进行修改.

零拷贝有两种方式:

  1. mmap+write

    优点:即使频繁调用,使用小块文件传输,效率也很高

    缺点:不能很好的利用 DMA 方式,会比 sendfile 多消耗 CPU,内存安全性控制复杂,需要避免 JVM Crash

    问题。

  2. sendfile

    优点:可以利用 DMA 方式,消耗 CPU 较少,大块文件传输效率高,无内存安全新问题。

    缺点:小块文件效率低于 mmap 方式,只能是 BIO 方式传输,不能使用 NIO。

Rocket选择的是第一种方式来提高消息存盘和网络发送的速度。

这种机制在java中是通过MappedByteBuffer实现的.

这里需要注意的是,采用MappedByteBuffer这种内存映射的方式有几个限制,其中之一是一次只能映射1.5~2G 的文件至用户态的虚拟内存,这也是为何RocketMQ默认设置单个CommitLog日志数据文件为1G的原因了

文件系统

RocketMQ 选择 Linux Ext4 文件系统,原因如下:

Ext4 文件系统删除 1G 大小的文件通常耗时小于 50ms,而 Ext3 文件系统耗时约 1s 左右,且删除文件时,磁盘IO 压力极大,会导致 IO 写入超时。

文件系统 IO 调度算法需要调整为 deadline,因为 deadline 算法在随机读情况下,可以合并读请求为顺序跳跃方式,从而提高读 IO 吞吐量。

数据存储结构

RocketMQ消息的存储是由ConsumeQueue和CommitLog配合完成的,除此之外还有一个indexFile来提供根据key或者时间分区来查询消息的 方法.

CommitLog

CommitLog是消息真正的物理存储文件,并且一个Broker中的所有消息不区分topic均存储在一个CommitLog中.CommitLog是完全的顺序写,随机读,每个CommitLog文件的大小为1G,超过了则新建一个新的CommitLog,CommitLog文件名按照偏移量顺序命名.

ConsumeQueue

ConsumeQueue是消息的逻辑队列,类似数据库的索引文件,存储的是消息在CommitLog的索引。每 个Topic下的每个Message Queue都有一个对应的ConsumeQueue文件。

IndexFile

为了消息查询提供了一种通过key或时间区间来查询消息的方法,这种通过IndexFile来查找消息的方法不影响发送与消费消息的主流程

消费模式

1. 集群模式

集群模式就是group模式,采用负载均衡的方式,每条消息都从每个group中选择一个消费者消息

2. 广播模式

每个group中的每个消费者都会收到同一个消息

负载均衡

发送负载均衡

在这里插入图片描述

Producer端,每个实例在发消息的时候,默认会轮询所有的message queue发送,以达到让消息平均落在不同的queue上。而由于queue可以散落在不同的broker,所以消息就发送到不同的broker下,如下图:

图中箭头线条上的标号代表顺序,发布方会把第一条消息发送至 Queue 0,然后第二条消息发送至 Queue 1,以此类推。

另外也可以自定义方式选择发往哪个队列。

订阅消息负载均衡

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值