【RocketMQ 消息中间件】RocketMQ篇之-消息存储 为什么性能高 CommitLog ConsumeQueue IndexFile 刷盘机制 同步 异步

RocketMQ篇之-消息存储

目录

RocketMQ作为一款分布式消息中间件,高可靠性是其最重要的特性之一。

所以需要将消息进行持久化存储,以保证消息不丢失。

RocketMQ的消息存储是RocketMQ的核心组件之一,负责消息的存储和传输。RocketMQ的消息存储主要包括CommitLog、ConsumeQueue、IndexFile、Checkpoint等几个部分。

(前置)消息存储交互流程

  1. 生产者发送消息MQ;
  2. MQ将消息存到存储系统;
  3. 返回消息存储结果;
  4. 消费者从存储系统拉取消息,消费消息;
  5. 消费者消费成功,返回消费结果;
  6. 存储系统删除消息。

(一)存储系统

在上面的流程中,存储系统是RocketMQ的核心组件之一,负责消息的读写。

存储系统有以下几种选择:

  1. 内存存储等;
  2. 关系型数据库存储;
  3. 文件存储;

在RocketMQ中,使用的是文件存储。

1. 内存存储

内存存储是一种高性能的存储方式,但是内存存储的数据是不稳定的,一旦断电,数据就会丢失。即便是以Redis为代表的内存数据库,也无法保证数据的持久化,在持久化方面,还是选择文件存储。所以对消息来说,内存存储是不适合的。

2. 关系型数据库存储

关系型数据库存储是一种常见的存储方式,像MySQL、Oracle等都可以作为消息存储。阿帕奇的ActiveMQ、Pulsar等都是使用关系型数据库作为消息存储。但其实关系型数据库底层也是文件存储,所以对比直接使用文件存储,关系型数据库存储的性能会有所下降。

3. 文件存储

文件存储是一种常见的存储方式,像Kafka、RocketMQ、RabbitMQ等都是使用文件存储。文件存储的优点是性能高,稳定性好,适合消息存储。

(二)消息的存储和发送

1. 消息存储(顺序写入)

磁盘的读写速度虽然比内存慢,但是和网络IO相比,磁盘的读写速度还是很快的。现在的磁盘读写速度已经达到了几百MB/s甚至上千MB/s,所以对于消息存储来说,磁盘的读写速度是足够的。

但是在随机读写方面,磁盘的性能就会有比较严重的下降,所以RocketMQ的消息存储是顺序写入的,这样可以提高磁盘的读写性能。

2. 消息发送(零拷贝)

消息的发送,需要将磁盘内的数据发送到网络中,在这个过程中,会涉及到系统的内核态和用户态的切换,这个过程是比较耗时的。

把磁盘数据发送到网络中,需要经过以下几个步骤:

  1. 从磁盘中读取数据;
  2. 将读取的数据发送到网络中;

看似只有两个步骤,但是在实际的操作中,还会涉及到内核态和用户态的切换和数据复制等操作:

  1. 从磁盘中读取数据,磁盘复制 -> 内核态的缓冲区;
  2. 内核态的缓冲区复制 -> 用户态的缓冲区;
  3. 将数据发送到网络中,从用户态的缓冲区复制 -> 网络驱动的内核态缓冲区;
  4. 网络驱动的内核态缓冲区复制 -> 网络中;

重要‼️:RocketMQ通过mmap的方式将磁盘文件映射到内存中,这样可以减少内核态和用户态的切换,减少数据的复制,提高性能,也就是所谓的零拷贝。

(三)存储文件结构

在RocketMQ中,有三个重要的文件类型:commitlog、consumequeue和index文件。它们分别有不同的用途和存储内容。

1. CommitLog

用途:

CommitLog文件是RocketMQ存储消息的核心文件。所有的消息首先都会被写入到CommitLog文件中。

它以顺序写的方式保存消息,以确保写入的高性能和可靠性。

存储内容:

CommitLog文件存储的是消息的完整内容,包括消息的元数据(如消息ID、主题、队列ID等)和消息体。

联系:

所有消息最初都会写入到CommitLog文件中,然后再由消息服务组件(例如:ConsumeQueue和IndexFile)进行进一步的处理。

2. ConsumeQueue

用途:

ConsumeQueue是RocketMQ的消费者队列文件,主要用于提高消息消费的效率。

它相当于消息的索引文件,消费者可以通过ConsumeQueue快速定位到需要消费的消息在CommitLog中的位置。

存储内容:

ConsumeQueue文件存储的是消息在CommitLog中的物理偏移量、消息大小和消息的标签哈希值。

联系和区别:

ConsumeQueue是从CommitLog文件中生成的,用于加速消息消费。它只存储消息的索引信息,而不是消息的完整内容

3. IndexFile

用途:

IndexFile是RocketMQ的索引文件,主要用于通过消息的索引(例如:消息的唯一标识符Key)快速查找消息。

它实现了基于哈希的索引机制,支持消息的快速检索。

存储内容:

IndexFile文件存储的是消息的Key(唯一标识符)、消息的物理偏移量和消息的存储时间。

联系和区别:

IndexFile也是从CommitLog文件中生成的,但它的目的是为了提供消息的快速检索功能。

与ConsumeQueue不同,IndexFile是通过消息的Key来查找消息,而不是通过主题和队列。ConsumeQueue是通过消息的主题和队列ID来查找消息。

总结

CommitLog:RocketMQ中存储所有消息的核心文件,保存消息的完整内容。

ConsumeQueue:消费者队列文件,用于加速消息消费,存储消息的索引信息。

IndexFile:索引文件,用于快速检索消息,存储消息的Key和物理偏移量。

这三种文件共同协作,确保了RocketMQ的高性能和高可靠性。CommitLog负责消息的存储,ConsumeQueue提高了消息的消费效率,而IndexFile则提供了消息的快速检索能力。

(四)刷盘机制

RocketMQ的消息存在磁盘中,这样能保证在断电后消息不会丢失。

在消息写入磁盘的过程中,有两种刷盘机制:同步刷盘和异步刷盘。

1. 同步刷盘

同步刷盘是指在消息写入磁盘后,需要等待磁盘的写入操作完成后,才返回写入成功的结果。

同步刷盘的优点是数据安全,可以保证消息不会丢失。但是同步刷盘的缺点是性能较差,因为需要等待磁盘的写入操作完成后才能返回结果。

2. 异步刷盘

异步刷盘是指在消息写入磁盘后,不需要等待磁盘的写入操作完成,可以立即返回写入成功的结果,然后由后台线程负责将数据刷盘到磁盘中。

异步刷盘的优点是性能较好,因为不需要等待磁盘的写入操作完成,可以立即返回结果。但是异步刷盘的缺点是数据不安全,可能会丢失部分消息。

选择

在实际的应用中,可以根据业务的需求选择合适的刷盘机制。如果对数据的安全性要求较高,可以选择同步刷盘;如果对性能要求较高,可以选择异步刷盘。

总结

RocketMQ的消息存储是RocketMQ的消息持久化的方式,保证消息不会丢失。

我们讲了以下几部分相关的内容:

  1. 存储系统的选择,选择了文件存储。
  2. 消息的存储和发送,通过顺序写入和零拷保证性能。(也是RocketMQ为什么高性能的主要原因)
  3. 存储文件结构,CommitLog、ConsumeQueue和IndexFile。
  4. 刷盘机制,同步刷盘和异步刷盘。

这些内容是RocketMQ消息存储的核心内容,对于理解RocketMQ的消息存储机制非常重要。希望本文对你有所帮助,如果有任何问题,欢迎留言讨论。

相关推荐
老K(郭云开)7 小时前
最新版Edge浏览器加载ActiveX控件技术——allWebPlugin中间件之awp_CreateActiveXObject接口用法
前端·javascript·chrome·中间件·edge
小馋喵知识杂货铺1 天前
Nginx 集群测试
中间件
小白的一叶扁舟1 天前
Elasticsearch(ES)与 MySQL 的对比分析及在 Spring Boot 中的使用
java·数据库·spring boot·后端·mysql·elasticsearch·中间件
m0_748240441 天前
【ROS2 中间件RMW】基于FastDDS共享内存实现ROS2跨进程零拷贝通讯
中间件
mikey棒棒棒1 天前
RabbitMQ-消息可靠性以及延迟消息
java·开发语言·中间件·rabbitmq·消息可靠性·死信交换机·惰性队列
m0_748233641 天前
【服务治理中间件】consul介绍和基本原理
中间件·consul
声声codeGrandMaster1 天前
Scrapy中间件的使用
python·scrapy·中间件
m0_748236111 天前
国产化中间件东方通TongWeb环境安装部署(图文详解)
中间件
m0_748238921 天前
开源数据同步中间件(Dbsyncer)简单玩一下 mysql to mysql 的增量,全量配置
mysql·中间件·开源