RocketMQ中的消息存储结构及删除机制

RocketMQ的存储设计


Message

Message是Rocket中很重要的组成部分,也就是消息本身。Message中有messageId,messageKey。message和Topic是多对一的关系,一个主题下边可以有多个消息。

Topic

Topic中有tags和subTopics。每条消息都有对应的Topic,一个Topic下会有多个消息。生产者生产消息的时候会指定Topic,消费者读取消息的时候,会获取指定Topic的消息。

Group

Group,一般会有生产者分组,消费者分组,一个Group可以消费多个Topic,一个Topic也可以被多个Group消费。一般同一个分组的消费者拥有同样的消费行为。

Queue

Queue是队列,也就是存储尚未消费的消息的地方,一般会设置多个,所以一个Topic下边一般会有多个Queue

Offset

Offset是消息偏移量。

消息存储结构

RocketMQ是高可用的,也是因为其对消息等数据进行了持久化存储,对应的存储文件如下所示。



RocketMQ 消息的存储是由 ConsumeQueue 和 CommitLog 配合完成的,消息真正的物理存储文件是 CommitLog,ConsumeQueue 是消息的逻辑队列,类似数据库的索引文件,存储的是指向物理存储的地址。每 个 Topic 下的每个 Message Queue 都有一个对应的ConsumeQueue 文件。

Commitlog

Commitlog是消息存储的目录,所有的消息写入的时候,都会写入到commitlog文件中,并且会存储消息的元数据,也就是消息的Topic,Message,Queueid等信息都会被保存。

CommitLog消息存放的时候,每条消息的前边四个字节存储该消息的总长度。由于消息其他信息长度不固定,所以一个消息的存储长度是不固定的。

每个CommitLog的文件大小为1G,第一个文件的起始偏移量为0,第二个则为1073741824,因为1G=1073741824byte。当写入的时候,会先往同一个文件写,等写满之后,再写入下一个。

CommitLog这样顺序写,会大大的提高写入的效率。

当消息到达Commit文件之后,会有专门的线程产生消息转发任务,从而构建ConsumeQueue文件与Index文件。

ConsumeQueue


消息的逻辑队列,是CommitLog的索引文件,存储的是指向物理存储的地址。每个Topic下的每个MessageQueue都有一个ConsumeQueue文件。在ComsumeQueue文件中,每个节点内包含该消息在Commitlog的偏移量,对应消息的大小,Tag的HashCode。

ConsumeQueue中存储的并不是消息的全量数据,是为了增加查询速度的索引文件

因为ConsumeQueue的占用内存很小,一般可以全部读入到内存中,这样对ConsumeQueue的操作是极快的。

IndexFile


消息索引文件,当使用messageKey检索消息的时候,就是读取的IndexFile文件,这个文件的存在大大提高了检索消息的速度,是RocketMQ专门为消息订阅构建的索引文件。

Config

Broker配置信息

  • topics.json : topic 配置属性,RocketMQ创建了几个topic,每个主题有多少队列,每个队列又是怎么样的,都会存储在这个文件中。
  • subscriptionGroup.json :消息消费组配置信息。
  • delayOffset.json :延时消息队列拉取进度。
  • consumerOffset.json :集群消费模式消息消进度。
  • consumerFilter.json :主题消息过滤信息。

其他文件

abort

记录Broker是否正常关闭,这是一个空文件,当Broker正常关闭的时候,会删除abort文件。但是当异常宕机或其他原因关闭的时候,则不做删除处理。

checkpoint

文件检查点,记录Commit最后一次刷盘的时间,consumequeue最后一次刷盘时间,index索引文件最后一次刷盘时间

消息删除机制

为了避免内存与磁盘的浪费,RocketMQ有专门的删除机制来删除过期的文件。

消息消费队列文件与消息存储文件( Commitlog )共用一套过期文件机制。

清理的逻辑是:如果非当前写文件在一定时间间隔内没有再次被更新,则认为是过期文件,可以被删除, RocketMQ 不会关注这个文件上的消息是否全部被消费。

通过在 Broker配置文件中设置 fileReservedTime 来改变过期时间,默认为48,单位为小时。

触发文件清除操作的是一个定时任务,而且只有定时任务可以执行这个操作,默认每 10s 执行一次。

过期判断

fileReservedTime是允许文件保留的最长时间,当文件最后一次更新的时间到现在的时间超过这个时间了。那么这个文件将被删除。

还有两个参数:

  • deletePhysicFilesInterval:删除间隔默认100ms,若是有多个文件同时过期,并不会同时删除多个文件,而是间隔deletePhysicFilesInterval时间后继续删除。

  • destroyMapedFileIntervalForcibly:当删除某个文件的时候,若是该文件还在被引用,将阻止删除操作。destroyMapedFileIntervalForcibly则表示当第一次删除拒绝之后,删除免疫的时间,在这个时间内将一直拒绝删除,超过这个时间之后,则可以被删除。

删除条件

指定时间删除

可以通过deleteWhen设置一天执行一次删除文件的操作,默认是凌晨4点。

磁盘满删除

DiskSpaceCleanForciblyRatio参数是磁盘占用的阈值。

检查磁盘是否充足,若是磁盘占用超过百分之85(默认),则会触发过期文件删除操作。

#java#
全部评论

相关推荐

喜欢走神的孤勇者练习时长两年半:池是池,发是发,我曾池,我现黑
点赞 评论 收藏
分享
勤奋努力的椰子这就开摆:美团骑手在美团工作没毛病
投递美团等公司10个岗位
点赞 评论 收藏
分享
点赞 1 评论
分享
牛客网
牛客企业服务