我们知道 RocketMQ 是一款高性能、高可靠的分布式消息中间件,高性能和高可靠是很难兼得的。因为要保证高可靠,那么数据就必须持久化到磁盘上,将数据持久化到磁盘,那么可能就不能保证高性能了。

RocketMQ 在兼容这两方面做的不错,先从磁盘说起,现代的磁盘都是高性能的,写速度并不一定比网络的数据传输速度慢。比如 SSD 固态硬盘在 M.2 NVMe协议下,顺序写的速度可以达到 1500 MB/s,就算是普通磁盘,如果性能比较高的话,顺序写的速度可以达到 450MB/s~600MB/s。

在顺序写的情况下是这速度,但是不人为控制的话,磁盘采用的是随机写,在随机写的情况下,磁盘的写入速度急速下降,磁盘的随机写速度可能只有几百KB/s,这远远要慢于网络传输速度,所以它并不能满足高性能的要求

RocketMQ 在持久化的设计上,采取的是消息顺序写、随机读的策略,利用磁盘顺序写的速度,让磁盘的写速度不会成为系统的瓶颈。并且采用 MMPP 这种“零拷贝”技术,提高消息存盘和网络发送的速度。极力满足 RocketMQ 的高性能、高可靠要求。

上述从硬件的角度聊聊了高性能的保证,这些咱也不懂,还是来看看 RocketMQ 持久化机制的架构图吧。

在 RocketMQ 持久化机制中,涉及到了三个角色:

  • CommitLog:消息真正的存储文件,所有消息都存储在 CommitLog 文件中。
  • ConsumeQueue:消息消费逻辑队列,类似数据库的索引文件。
  • IndexFile:消息索引文件,主要存储消息 Key 与 offset 对应关系,提升消息检索速度。

咱们逐一聊聊吧,CommitLog 文件是存放消息数据的地方,所有的消息都将存入到 CommitLog 文件中。生产者将消息发送到 RocketMQ 的 Broker 后,Broker 服务器会将消息顺序写入到 CommitLog 文件中,这也就是 RocketMQ 高性能的原因,因为我们知道磁盘顺序写特别快,RocketMQ 充分利用了这一点,极大的提高消息写入效率。

但是消费者消费消息的时候,可能就会遇到麻烦,每一个消费者只能订阅一个主题,消费者关心的是订阅主题下的所有消息,但是同一主题的消息在 CommitLog 文件中可能是不连续的,那么消费者消费消息的时候,需要将 CommitLog 文件加载到内存中遍历查找订阅主题下的消息,频繁的 IO 操作,性能就会急速下降

为了解决这个问题,RocketMQ 引入了 Consumequeue 文件。Consumequeue 文件可以看作是索引文件,类似于 MySQL 中的二级索引。在存放了同一主题下的所有消息,消费者消费的时候只需要去对应的 Consumequeue 组中取消息即可。Consumequeue 文件不会存储消息的全量信息,了解 MySQL 索引的话,应该好理解这里,具体存储的字段,我在上图已经标注。这样做可以带来以下两个好处:

  • 由于 Consumequeue 文件内容小,可以尽可能的保证 Consumequeue 文件全部读入到内存,提高消费效率。
  • Consumequeue 文件也是会持久化的,不存全量信息可以节约磁盘空间。

IndexFile 是 RocketMQ 为消息订阅构建的索引文件,用来提高根据主题与消息队列检索消息的速度,这个就不细说了。

RocketMQ 持久化机制原理差不多就这些了,接下来聊一聊消息数据刷盘吧。

因为操作系统 PAGECACHE 的存在,PageCache是OS对文件的缓存,用于加速对文件的读写,所以一般都是先写入到 PAGECACHE 中,然后再持久化到磁盘上。我们熟悉的其他组件,MySQL、Redis 等都是如此。RocketMQ 也不列外。

在 RocketMQ 中提供了同步刷盘异步刷盘两种刷盘方式,可以通过 Broker 配置文中中的 flushDiskType 参数来设置(SYNC_FLUSH、ASYNC_FLUSH)。

异步刷盘方式(默认):消息写入到内存的 PAGECACHE中,就立刻给客户端返回写操作成功,当 PAGECACHE 中的消息积累到一定的量时,触发一次写操作,将 PAGECACHE 中的消息写入到磁盘中。这种方式吞吐量大,性能高,但是 PAGECACHE 中的数据可能丢失,不能保证数据绝对的安全

同步刷盘方式:消息写入内存的 PAGECACHE 后,立刻通知刷盘线程刷盘,然后等待刷盘完成,刷盘线程执行完成后唤醒等待的线程,返回消息写成功的状态。这种方式可以保证数据绝对安全,但是吞吐量不大

关于RocketMQ 持久化机制的分享就这些,感谢您的阅读,希望这篇文章对您的学习或者工作有一点帮助。有收获的话,也可以帮忙推荐给其他的小伙伴,让更多的人受益,万分感谢

欢迎关注公众号【互联网平头哥】。这里有职场感悟、Java 技术,虽然不高大上,但通俗易懂。今天最好的是明天最低的要求,愿你我共同进步。

探秘 RocketMQ 消息持久化机制的更多相关文章

  1. ActiveMQ的几种消息持久化机制

    为了避免意外宕机以后丢失信息,需要做到重启后可以恢复消息队列,消息系统一般都会采用持久化机制. ActiveMQ的消息持久化机制有JDBC,AMQ,KahaDB和LevelDB,无论使用哪种持久化方式 ...

  2. ActiveMQ的消息持久化机制

    为了避免意外宕机以后丢失信息,需要做到重启后可以恢复消息队列,消息系统一般都会采用持久化机制. ActiveMQ的消息持久化机制有JDBC,AMQ,KahaDB和LevelDB,无论使用哪种持久化方式 ...

  3. Rocketmq消息持久化

    本文编写,参考:https://my.oschina.net/bieber/blog/725646 producer Send()的Message最终将由broker处理,处理类为:SendMessa ...

  4. RabbitMQ消息确认机制

    文章目录 1. 事务机制2. Confirm模式2.1 生产者2.1.1 普通Confirm模式2.1.2 批量Confirm模式2.1.3 异步Confirm模式2.2 消费者3. 其他 消费者如何 ...

  5. JMS学习八(ActiveMQ消息持久化)

    ActiveMQ的消息持久化机制有JDBC,AMQ,KahaDB和LevelDB,还有一种内存存储的方式,由于内存不属于持久化范畴,而且如果使用内存队列,可以考虑使用更合适的产品,如ZeroMQ.所以 ...

  6. Rabbit MQ 消息确认和持久化机制

    一:确认种类 RabbitMQ的消息确认有两种.一种是消息发送确认,用来确认生产者将消息发送给交换器,交换器传递给队列的过程中消息是否成功投递.发送确认分为两步,一是确认是否到达交换器,二是确认是否到 ...

  7. ActiveMQ持久化机制和JMS可靠消息

    1.ActiveMQ持久化机制 1.1 JDBC将数据持久化到数据库 1.2 AMQ生成日志文件 1.3 KahaDB:本次磁盘生成数据文件(默认) 1.4 LevelDB:谷歌K/V数据库 1.5 ...

  8. RocketMQ(消息重发、重复消费、事务、消息模式)

    分布式开放消息系统(RocketMQ)的原理与实践 RocketMQ基础:https://github.com/apache/rocketmq/tree/rocketmq-all-4.5.1/docs ...

  9. RocketMQ消息丢失解决方案:事务消息

    前言 上篇文章,王子通过一个小案例和小伙伴们一起分析了一下消息是如何丢失的,但没有提出具体的解决方案. 我们已经知道发生消息丢失的原因大体上分为三个部分: 1.生产者发送消息到MQ这一过程导致消息丢失 ...

随机推荐

  1. vue相关坑

    1:vue 动态加载图片路径报错解决方法,循环遍历图片不显示图片 解决方法:https://www.cnblogs.com/qingcui277/p/8930507.html

  2. 简单的猜数字小游戏--Python

    猜数字小游戏: #coding=utf-8 import random   answer =random.randint(1,100) #生成随机数 n=int (input("Please ...

  3. React-redux: React.js 和 Redux 架构的结合

    通过Redux 架构理解我们了解到 Redux 架构的 store.action.reducers 这些基本概念和工作流程.我们也知道了 Redux 这种架构模式可以和其他的前端库组合使用,而 Rea ...

  4. [头脑风暴] 解读Docker Bridge网络模型

    背景 这几天在研究Kubernetes, 遇到一个有意思的nodejs镜像:luksa/kubia # 不带端口映射启动容器docker run -it -d luksa/kubia# 连接到默认的B ...

  5. (转)GNU风格ARM汇编语法指南(非常详细)4

    原文地址:http://zqwt.012.blog.163.com/blog/static/12044684201011148226622/ 4.GNU汇编语言定义入口点 汇编程序的缺省入口是_sta ...

  6. 附014.Kubernetes Prometheus+Grafana+EFK+Kibana+Glusterfs整合解决方案

    一 glusterfs存储集群部署 注意:以下为简略步骤,详情参考<附009.Kubernetes永久存储之GlusterFS独立部署>. 1.1 架构示意 略 1.2 相关规划 主机 I ...

  7. GoJS学习笔记 (转)

    目录 基础概念 开始绘制图形 1. 通过代码构建图形 2. 通过 GraphObject.make 构建图形 3. 使用 Model 和 Templates 创建图形 获取图形数据 获取所有 Node ...

  8. Code Index: 基于Lucene.Net的代码检索工具

    目录 用途 Github地址 示例 特性 用途 维护一个拥有巨大代码量的项目, 依靠自带的代码搜索工具搜索速度缓慢, 一个快速的代码检索工具就显得极为必要, 所以自己撸了个小工具. Github地址 ...

  9. ajax上传文件,通过FromData把数据传给后端

    前端代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  10. 直方图均衡算法(Histogram Equalized)

    Lab1: Histogram Equalization 1. 实验环境(C++) 操作系统版本 MacOS Catalina 10.15 OpenCV4.0 (imgcodecs | core | ...