ROCKETMQ消息存储

ROCKETMQ消息存储

ROCKETMQ存储采用存储文件的方式,使用netty作为通信框架,消息生产者发送消息后,将报文解析为RemotingCommand类,然后按照顺序进行消息存储。同时将消息的物理偏移量记录到messageId中,同时会生成索引文件:consumerQueue,indexFile,这两个文件中记录消息的物理偏移量,方便查账消息
查找消息时,都是根据索引文件记录的消息偏移量进行查找。

主要存储文件

  1. commitlog:消息内容存储文件。消息到达broker后进行存储
    路径:ROCKET_HOME/store/commitlog/*
  2. consumeQueue:消息消费队列存储文件,消息存储到commitlog文件后,将会异步转发到该文件,主要用于消息消费根据topic拉取文件。也支持根据topic和queueid以及时间戳进行查找
    路径:ROCKET_HOME/store/consumequeue/tipic/queueid/*
  3. indexFile:消息索引文件,发送消息是设置的key会添加到此文件进行索引,方便根据key,快速找到消息

存储流程

  1. 接收到生产者的请求后,解析为 MessageExtBrokerInner 类,执行CommitLog.putMessage方法进行存储消息,从当前的wrotePosition 位置开始,按照一定格式存储进最后一个 commotLog文件中(默认1G)。
  2. 同时异步将commotLog中新增的消息转发到ConsumeQueue文件和indexFile文件中。
  • commitLog消息格式: 总大小(4)+魔数(4)+CRC校验码(4)+队列id(4)+FLAG(4)+队列偏移量(8)+物理偏移量(8)+SYSFLAG(4)+生产时间戳(8)+消息发送者ip(8)+存储时间戳(8)+存储服务ip,port(8)+消息重试次数(4)+事务消息物理偏移量(8)+消息长度(4)+消息内容(上一个值)+TOPIC长度(1)+TOPIC(上一个值)+消息属性长度(2)+消息属性(上一个值)
  • consumeQueue文件格式:指向commitLog的消息物理偏移量(8)+消息总大小(4)+tag hashCode(8)
  • indexFile 文件格式 :40文件属性信息+500W个hash槽+2000W个消息index。hash槽格式为: index的位置(4);index条目格式为: key hashCode(8)+消息物理偏移量(8)+和当前文件第一条消息的时间戳差值(4)+上一个消息index的位置(4)
    • 为什么index笔hash槽多个,因为要处理hash槽冲突的情况,一个hash槽可能会对应多个index条目。每次通过hash槽的值找到index条目都要对比hashCode是否一致,同时循环通过上一个消息的index位置继续找,直到没有上一个。同时通过物理偏移量找到真实消息信息后还要再次校验key原值,防止hash值冲突导致找错信息。
  1. 代码入口:
    org.apache.rocketmq.broker.processor.SendMessageProcessor#asyncProcessRequest
    SEND_MESSAGE_V2 格式是为了缩短报文长度。

其他文件

  1. checkpoint 文件记录了上面三种文件最后一次的刷盘时间点。
  2. config/* 记录了每个topic 的配置信息
  3. abort 文件代表文件是否正常关闭,正常启动是生成,正常关闭是删除。
    • 如果当启动时abort 文件存在,则代表上一次是非正常关闭

启动时加载文件

  1. 首先加载所有commitlog 文件
  2. 加载所有consumeQueue文件
  3. 加载所有indexFile文件
  4. 判断abort 文件是否正常,正常关闭时,会校验倒数三个 commitlog文件里的所有消息crc,将最后一个校验通过的消息之后的文件和内容全部清除(防止发送错误消息)。如果非正常关闭,则校验最后一个commitlog文件里的所有消息是否正常,将正常的消息转发到 consumequeue和indexfile文件,同时将最后一个校验通过消息之后的内容全部清除。

文件持久化

MappedFile 里有几个重要参数分别是:writeBuffer :堆外内存,transientStorePool:堆外内存池,就是writeBuffer从这里获取,用完再归还,mappedByteBuffer:物理文件的映射内存。

  • 同步刷盘:每次写入的消息都直接提交到 物理文件的映射内存,同时force()刷到物理文件。
  • 异步刷盘
    参数 transientstorepooleenable为true且为异步刷盘
    则会开启堆外内存缓冲区,目的是减少刷盘频率;每次写入消息都会写入writeBuffer堆外内存,它会每200ms 将缓冲区的内存刷到物理文件的映射内存,但是限制每次必须提交 4页的内容(16K),不足4页就会限制频率。同时每500ms会将 文件的映射内存 force刷到物理文件。
    参数 transientstorepooleenable为false,则不开启 堆外内存缓冲区,每次写入消息都会直接写入 物理文件的映射内存,每500ms将映射内存 force刷到物理文件。
  • rocketmq默认为异步刷盘,每200ms 将缓冲区的内容刷到 映射内存,每500ms将映射内存的内容刷到物理文件

过期文件清除

rocketmq 每10s检查一次过期文件,超过72小时没有更新即为过期文件,会启动删除任务,首先会检测文件是否有引用,如果有则拒绝删除,同时记录当前时间戳(目的是超过一定时间,即使有引用也要强制删除),在此期间,每次拒绝都会减少1000引用,直到引用为0或超过最大存活时间被强制删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值