RabbitMQ——队列索引文件格式

简介

RabbitMQ的持久化包含两个部分:队列索引(queue index)和消息存储(message store)。

队列索引负责维护消息在队列中的位置信息,以及消息的状态(消息是否投递给消费者或被消费者确认)。因此每个队列都会有一个自己的队列索引。消息索引则是一个全局的KV存储,RabbitMQ中所有的消息均存储在这里。

从3.5.0版本开始,小的消息直接存储在队列索引中而不是存储在消息存储中。具体通过queue_index_embed_msgs_below进行配置,默认值为4096字节。即消息内容、属性以及headers长度累加小于4096的将直接存储在队列索引中。

每个队列都有自己的队列索引,队列索引文件后缀名为idx。

消息直接存储在索引中的好处是:仅需进行一次写操作,而存储在消息存储中的消息则需要两次写操作(一次写索引,一次写消息存储),因此会有一定的性能提升。但另一方面需要注意的是:如果一个消息通过exchange同时路由到多个队列中,消息会被写到每个队列的索引文件中。而如果消息是写入消息存储中,仅仅只有一个副本。


内部实现概念

描述索引文件格式前,先简单说下内部实现中的一些概念词

1、entry(条目)

队列中的每个消息就是一个entry

每个消息包括三种状态:

publish:  消息已投递到队列中

deliver:  消息已投递给消费者

ack:      消息已被消费者确认

每个消息必然从publish到deliver再到ack经过三种状态,一旦消息被消费者确认,那么这个消息就可以不在队列索引中进行存储。

对于每个publish的消息包括

SequenceID:消息在队列中的序号, 按进入队列的先后顺序编号

MessageID:消息的唯一ID

Metadata:元数据信息(包括属性、headers)

Message:消息的完整内容(可选), 对于比较小的消息而言

而每个deliver,ack只需要记录消息的SequenceID即可

2、segment(段)

存储固定长度的消息,其个数为16384,每个segment有固定的编号,编号从0开始,这意味着:

0号segment 存储SequenceID为 0-16383 的消息

1号segment 存储SequenceID为 16384-32767 的消息

以此类推


索引文件格式

前面讲到了每个消息都有publish,deliver,ack三种状态,而每种状态都有具体对应格式,索引文件内容就是按这些格式进行存储

publish对应的存储格式:

这里有几点需要说明下:

1)持久化位:1表示持久化、0表示非持久化

2)消息序号:表示在对应idx文件中的序号(14位最大能表示的值为16384),存储时先根据消息的SequenceID 除16384,计算出应该存在哪个idx文件中,然后求余得到在idx文件中的序号,反之根据idx文件的序号加文件中的消息序号可计算出消息真正的SequenceID

3)载荷长度:也就是具体消息内容的长度

4)总长度:消息内容、属性、headers加在一起的总长度,但是如果消息是存储在message_store中,总长度计算为0

deliver/ack对应的存储格式:

索引文件示例

以一个真实的索引文件举例说明:

按照前面的讲解来分析文件

C007其二进制为1100000000000111,第一位1,表示是publish到队列的消息,第二位也为1表示是一条持久化的消息;中间16字节为消息的唯一ID;紧接着8字节0为消息的有效期;再接下来的4字节00000400,对应十进制1024,即消息内容的长度为1024;再接下来4字节全部为0,表示消息在message_store中存储(而实际queue_index_embed_msgs_below配置为512,符合预期)。

再后又是一条publish的消息(C008),该消息的实际内容长度为7字节(00000007),消息内容加属性以及headers的总长度为304字节(00000130)。

跳过304字节看到连续两个4007(二进制为0100000000000111),前缀为01,表示序号为00000000000111的消息已经deliver给消费者,并且已经被消费者确认。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值