RocketMQ 的存储机制了解吗?

参考答案

RocketMQ 采用文件系统进行消息的存储,相对于 ActiveMq 采用关系型数据库进行存储的方式,更加直接、性能更高。

RocketMQ 与 Kafka 在写消息与发送消息上,继续沿用了Kafka 的这两个方面:顺序写、零拷贝。

1    顺序写

操作系统每次从磁盘读写数据时,都要找到数据在磁盘上的地址,再进行读写。如果是机械硬盘,寻址需要的时间往往会比较长。通常,把数据存储在内存上面,少了寻址的过程,性能就会好很多。

但是,Kafka 的数据存储在磁盘上面,依然性能很好,这是为什么呢?

原因是 Kafka 采用的是顺序写,直接追加数据到末尾。

实际上,磁盘顺序写的性能极高,在磁盘个数一定,转数一定的情况下,基本和内存速度一致。因此,磁盘的顺序写这一机制,极大地保证了 Kafka 本身的性能。

2    零拷贝

例如:读取文件,再用 Socket 发送出去的这个过程。

buffer = File.read
Socket.send(buffer)

传统方式实现:先读取再发送

实际上,会经过以下四次复制

  • 将磁盘文件,读取到操作系统内核缓冲区 Read Buffer
  • 将内核缓冲区的数据,复制到应用程序缓冲区 Application Buffer
  • 将应用程序缓冲区 Application Buffer 中的数据,复制到socket网络发送缓冲区
  • 将 Socket buffer 的数据,复制到网卡,由网卡进行网络传输

RocketMQ 的存储机制了解吗?

传统方式,读取磁盘文件并进行网络发送,经过的四次数据 copy ,操作非常繁琐。

重新思考传统 IO 方式,我们会注意到,在读取磁盘文件后,不需要做其他处理,直接用网络发送出去的这种场景下,第二次和第三次数据的复制过程,不仅没有任何帮助,反而带来了巨大的开销。

使用零拷贝,则直接由内核缓冲区 Read Buffer ,将数据复制到网卡,省去第二步和第三步的复制。

采用零拷贝的方式发送消息,必定会大大减少读取的开销,使得 RocketMQ 读取消息的性能有一个质的提升。

此外,还需要再提一点,零拷贝技术采用了 MappedByteBuffer 内存映射技术,采用这种技术有一些限制,其中有一条就是传输的文件不能超过 2G ,这也就是 RocketMQ 存储消息的文件 CommitLog 的大小规定为 1G 的原因。

总结:

RocketMQ 采用文件系统存储消息,并采用顺序写写入消息,使用零拷贝发送消息,极大得保证了 RocketMQ 的性能。

 

以上,是消息队列 RocketMQ 面试题【RocketMQ 的存储机制了解吗?】的参考答案。

输出,是最好的学习方法

欢迎在评论区留下你的问题、笔记或知识点补充~

—end—

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧