ROCKETMQ消息存储(待完善)

文章目录

  • 一、接受到消息存储流程
  • 二、文件组织与内存映射。

一、接受到消息存储流程

无论是Commitlog还是ConsumeQUeue还是IndexFile,都是固定长度,写满后创建新文件,文件名第一条消息对应的全局物理偏移量。

  1. 校验消息。
  2. 如果是延迟消息,将原消息主题和消息队列iD存到消息属性properties中,然后用延迟消息主题,队列ID替换原消息主题。
  3. 获取当前的commitLog物理文件
  4. 获取commitLog的put锁,也就是把消息存储到commitLog文件中是串行的。
  5. 设置消息的存储时间。
  6. 将消息追加到内存映射文件的byteBuffer中。
    1. 创建全局唯一消息ID
    2. 获取该消息在消息队列中的偏移量,commitLog中保留了当前所有消息队列当前待写入的偏移量。
    3. 计算消息总长度,消息是不定长的,前4个字节是消息总长度。
      10.如果消息长度大于剩余空间,则返回END_OF_FILE, Broker会重新创建一个commitLog文件。每个commitLog最后最少留8个字节,高4字节记录当前文件剩余空间,低4字节记录魔数。
      11.将消息写入内存的ByteBuffer中,返回追加结果AppendMessageResult,后续根据刷盘策略进行刷盘。
  7. 更新消息队列偏移量
    13 释放put锁
  8. 根据刷盘策略刷盘。

二、文件组织与内存映射。

MappedFile是内存映射文件具体实现,通过fileChannel.write和mappedByteBuffer.force有什么区别
有两种方式,一种是通过堆外内存writeBuffer,通过fileChannel.write写入文件,fileChannel.force刷盘
另外一种是直接用mappedByteBuffer.fore刷盘。
同时维护了commit指针和write指针还有刷盘指针。

你可能感兴趣的:(中间件)