前言
之前写过一篇关于RockerMQ的消息存储,本文接上文,这里是详细介绍RocketMQ是怎么完成消息读写的!
消息写
一条消息进入到Broker后经历一下几个过程才最终被持久化
- Broker更具QueueId,获取到该消息对应索引条目在consumerqueue目录中的写入偏移量,即QueueOffset
- 将queueId、queueOffset等数据,与消息一起封装为消息单元
- 将消息写入到commitLog
- 形成消息索引条目
- 将消息索引条目拆分到相应的consumerqueue
消息读
当Consumer来拉取消息时会经历以下几个步骤
- Consumer获取到其要消费消息所在的Queue的消息偏移量offset,计算出其要消费的消息offset
消费offset即消息消费进度,Consumer对某个queue消费的offset,即消费到了该queue的第几条消息,消息offset=消费offset+1,这里实际上就是去读config目录下consumerOffset.json文件
举例topic为first-topic-str,消费者为my-consumer-group,订阅队列有queue0-3.对应消费为0号消费到2,1号消费到2,2号消费到1,3号消费到1
- Consumer向Broker发送拉取请求,其中会包含拉取消息的Queue,消息offset及消息Tag
- Broker计算改ConsumerQueue中的queueOffset
queueOffset=消息offset*20字节
- 该queueOffset处开始向后查找第一个指定Tag的索引条目
- 解析该索引条目前8个字节,即可定位到该消息在commitLong中的commit Offset
- 从对应的commitLog offset中读取消息单元,并发送给Consumer
补充消息点位重置
这里关于consumerOffset.json文件,这个文件就是记录每个Topic下消费者消息的点位信息的
我们在rocket-console控制台中关于Topic中有一个重置消费位点的概念,操作如下
用过rocketmq的管理控制平台的同学应该都会看到重置消费位点这个功能,由于消费消息也只是对应的消费者的指针的偏移,消息也并没有消失,所以这个重置消费位点也就是指针的来回移动偏移而已。这里也很好理解,首先选择消费组,就是你订阅了这个topic的组,下边的时间点就是你要讲指针移动到什么时候,这个好像不能精确到其中的一条消息,只能通过时间来定位。然后就是重置后你选的消费组就开始从你选择的时间点开始消费消息,不过呢这个好像有点小bug还是怎么的 我测试的时候它的时间点好像并没有多么精确 大家可以自行测试。
还有一点 最重要的一点,这个重置消费位点你点过重置后它不会立马重置,你的消费者也不会立马接收到消息,点过重置后,好像会导致消息短暂的失效(这个时间好像是0-3分钟的样子,所以得等一下)
,那么这里实际上重置的数据就是上面提到的consumerOffset.json文件