开发者学堂课程【RocketMQ 知识精讲与项目实战(第三阶段):RocketMQ 消息存储结构】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/704/detail/12449
RocketMQ 消息存储结构
内容介绍:
一、消息存储结构
二、总结
一、消息存储结构
RocketMQ 搭建集群时做过存储目录的配置,先对 rocketMQ 进行连接,找到 rocketmq-1,连接135节点。进入 root it test ,之前的 rocketMQ 装在 user/local/rocketmq 目录下,存在一个 conf 文件夹。使用双组双存的方式,进入到 2m-2s-sync 。之前的135使用到两个配置文件, broker-a 和 broker-b.s 另外两个broker-a.s 和 broker-b 是138的节点配置文件。
如何进行配置,查看 Linux 文件的一种简便方式,相比于输入命令进行查看的繁琐复杂。我们可以打开 note paid++ 安装 NppFTP 插件可以配置135或者其他 linux 连接的信息,配置完成就可以直接连接。想要查看某个目录下的信息,将文件路径拷贝,打开文件进行连接(如图所示),文件定位到图示位置,双击文件下载到本地,通过这种方式与查看本地文件一致。下图为文件示例样式。
文件中制作的和存储相关的配置,存储路径在图示加重位置。
进入到目录观察一下,发现在 /uar/local/rocketmq/atore-a-0 输入到目录位置,这是 broker-a 的存储目录,发现其中的文件夹,重点关注的有三个, commitlog、consumequeue、index, 这三个分别是什么意思?通过具象化的图示解释一下。在 rocketMQ 当中,发送给它的所有消息均会存储到 commitlog 当中。
在目录中查看 commitlog ,发现只有一个文件,具体辨别文件还是文件夹观察最前面的位置不是 B 则为文件。在这里产生了一个持久化的文件,rocketMQ 在进行消息存储的时候,为了保证存储的效率,使用到的是顺序写。为了保证读取的性能,使用的零拷贝技术。之前讲到的 commitlog 的大小限定是1G 。Commitlog-11-1h 回车进行创建文件。其中文件只有一个吗?实际上是存储文件较大的话,存满一个文件会再次创建一个文件进行存储,这些文件统一称为 commitlog 。
为什么这个文件设计的很大?因为要发送给当前消息终结键的所有的消息的原数据信息都将存储到其中,比如: topic、queueid、massage, 所有相关的信息均存入其中,所以该文件较大,一个存储完毕再自动连续下一个。再次创建的 commitlog 大小依然为1G ,存满再次创建第三个。了解到 commitlog 存储消息相关的元数据。所有的消息都在一个 commitlog 中存储,在进行查询会变得很麻烦。需要从其中一个个的查找,如何保证读的性能?如何从众多的1G 文件中找到我们需要的?其中涉及到的原理并不是很复杂的,它借助一个 consumerQueue 即消费逻辑队列,属于逻辑队列。里面存储了消息的索引。若消费者此时查找某一消息进行消费,不需要直接寻找 commitlog ,而是先查索引,在索引中找到某个消息的位置,然后到 commitlog 当中精准定位到消息。 consumerQueue 的作用是加快 commitlog 的读取速度。 consumerQueue 不进行消息的存储,只存储消息到索引。 consumerQueue 和 massageQueue 一一对应,在创建消息队列的同时会对应的产生一个 consumerQueue ,主要涉及到消息的偏移量,比如说当前消费最小的偏移量、当前已经消费的偏移量、最大消息的偏移量都会在 consumerQueue 进行存储。这就设想到另一个问题,如果 consumerQueue 丢失,该如何进行消费?分析即消费者进行消费时会读取 consumerQueue ,通过其找到 commitlog 对应的位置读取消息,如果 consumerQueue 丢失,则可以通过 commitlog 还原出来, commitlog 中存储着所有有关的信息,包括 consumerQueue ,所以 consumerQueue 并不会造成太大的影响。这就是 commitlog 和 consumerQueue 的作用。图示最下方还有一个 indexfile 在目录的什么位置呢?
(commitlog 的位置)
(consumerQueue 的位置)
一个 topic 有多个队列,一个队列对应的有 consumerQueue ,这两个文件大小一样吗?进过分析可知,对应的不同的 consumerQueue 文件大小不一样,因为其中只有偏移量对应的信息,数据都在 commitlog ,所以 consumerQueue 占用空间较小。
演示如下, commitlog 大小是一个 1G ,进入到 consumer Queue ,涉及到讲项目时的 paytopic ,每个队列中有什么,对应的就有一个 consumerQueue ,这个 consumerQueue 的大小是293K ,比较小。在读取文件的时候 linux 会将文件加载到内存当中,我们在内存中读取文件,速度会更快一些。consumerQueue 就是为了加快我们读取 commitlog 的速度, consumerQueue 相当于 commitlog 的索引文件。涉及到的 indexfile 里存在一个文件,文件大小为401MB ,indexfile 的作用又是什么呢?由图可知,其可以索引文件,这个索引文件的作用是什么呢?其实相比于 consumerQueue 是按照消息的偏移量读取数据。 indexfile 涉及到其他几种的方式,比如说可以通过消息的 key 进行查询,或者通过时间区间查询等一些其他条件查询 commitlog ,我们在索引消息用到 consumerQueue 比较多一些。
二、总结
消息发送回来会存储到 commitlog 当中,为了加快 commitlog 的读取速度,这时就会需要 consumerQueue , consumerQueue 存储了 commitlog 当中的一个消息量,相当于这个消息的索引。除了这两个文件。indexfile 提供其他方式索引,像是通过 key 或者时间区间的方式查询消息。这就是消息储存的基本说明。