RocketMQ 笔记2 文件存储

MappedFileQueue  代表一类文件集合,比如consumequeue/{topic}/{queueId}/目录下的所有文件
MappedFile 代表一个文件,是对这个文件操作的封装
CommitLog 代表所有的commitLog文件,里面有一个MappedFileQueue的字段
ConsumeQueue 代表了topic+queueId的所有consumeQueue文件,里面也有一个MappedFileQueue


DefaultMessageStore存储操作类
private final CommitLog commitLog;

    private final ConcurrentMap<String/* topic */, ConcurrentMap<Integer/* queueId */, ConsumeQueue>> consumeQueueTable;


    private final FlushConsumeQueueService flushConsumeQueueService;//consumeQueue文件刷盘线程


    private final CleanCommitLogService cleanCommitLogService;//定时清理commitLog线程


    private final CleanConsumeQueueService cleanConsumeQueueService;//定时清理consumeQueue线程


    private final IndexService indexService;//索引文件


    private final AllocateMappedFileService allocateMappedFileService;


    private final ReputMessageService reputMessageService;//监控commitLog文件有变化写consumeQueue


    private final HAService haService;






 1.org.apache.rocketmq.store.DefaultMessageStore.load()  加载文件过程
 org.apache.rocketmq.store.MappedFileQueue.load()中加载目录下所有文件,设置position
 mappedFile.setWrotePosition(this.mappedFileSize);
 mappedFile.setFlushedPosition(this.mappedFileSize);
 mappedFile.setCommittedPosition(this.mappedFileSize);
 这样的话假如最后一个文件没有写满,停机,再启动好像不会接着写这个文件,会重新新建一个后续文件写消息








 2.org.apache.rocketmq.store.DefaultMessageStore.putMessage(MessageExtBrokerInner) 写消息过程->
 this.commitLog.putMessage(msg) 拿到最后一个mappedFile文件,可能需要新建文件,使用这个文件写入 ->


 org.apache.rocketmq.store.MappedFile.appendMessage(MessageExtBrokerInner, AppendMessageCallback)
 如果writeBuffer不为null,会先写到writeBuffer缓存里面,后续又线程定时commit写到fileChannel里面,写消息格式


org.apache.rocketmq.store.CommitLog.DefaultAppendMessageCallback.doAppend(long, ByteBuffer, int, MessageExtBrokerInner)


 写完后wrotePosition增加写的长度






 3.org.apache.rocketmq.store.CommitLog.handleDiskFlush(AppendMessageResult, PutMessageResult, MessageExt) 刷盘过程
 同步刷盘:
 向GroupCommitService提交一个GroupCommitRequest,同时阻塞线程,等待刷盘结果
 GroupCommitService的doCommit方法,在刷盘(CommitLog.this.mappedFileQueue.flush(0))结束后唤醒上面的线程,返回最终结果


 异步刷盘:
 唤醒FlushRealTimeService,定时调用mappedFileQueue.flush刷盘






 4.consumeQueue文件的写入
 org.apache.rocketmq.store.DefaultMessageStore.ReputMessageService 启动后监控commitLog文件MaxOffset有无变化,
 当有变化时候
 SelectMappedBufferResult result = DefaultMessageStore.this.commitLog.getData(reputFromOffset) 拿到新消息,设置新的MaxOffset


 从ByteBuffer中读取消息内容,构建DispatchRequest,包含topic,topic,commitLogOffset,msgSize,tagsCode,有了这些就可以写consumeQueue文件了
 DispatchRequest dispatchRequest =
    DefaultMessageStore.this.commitLog.checkMessageAndReturnSize(result.getByteBuffer(), false, false);




调用DefaultMessageStore.this.doDispatch(dispatchRequest)
CommitLogDispatcherBuildConsumeQueue  写consumeQueue文件
CommitLogDispatcherBuildIndex 写index文件






5.文件结构
CommitLog
每个文件的大小默认为1G,commitlog的文件名fileName,名字长度为20位,左边补0,剩余为起始偏移量,比如 00000000000000000000 代表了第一个文件,起始偏移量为 0, 文件大小为 1G=1073741824; 当这个文件满了,第二个文件名字为 00000000001073741824


Consumequeue
消息起始物理偏移量(physical offset, long 8字节)+消息大小(int,4字节)+tagsCode(long 8字节) 
每个 cosumequeue 文件的名称 fileName,名字长度为 20 位,左边补零,剩余为起始偏量; 比如 00000000000000000000 代表了第一个文件,起始偏移量为 0,文件大小为 600W, 当第一个文件满之后创建的第二个文件的名字为00000000000006000000,起始偏移量为6000000,以此类推,第三个文件名字为00000000000012000000,起始偏移量12000000。消息存储的时候会顺序写入文件,当文件满了,写入下一个文件。






6.broker读消息过程
org.apache.rocketmq.broker.processor.PullMessageProcessor.processRequest(Channel, RemotingCommand, boolean) 收到拉取消息请求


org.apache.rocketmq.store.DefaultMessageStore.getMessage(String, String, int, long, int, MessageFilter) 使用DefaultMessageStore读消息


ConsumeQueue consumeQueue = findConsumeQueue(topic, queueId) 找到对应consumeQueue


SelectMappedBufferResult bufferConsumeQueue = consumeQueue.getIndexBuffer(offset) 读取指定偏移处的ConsumeQueue内容


long offsetPy = bufferConsumeQueue.getByteBuffer().getLong();
int sizePy = bufferConsumeQueue.getByteBuffer().getInt();
long tagsCode = bufferConsumeQueue.getByteBuffer().getLong();  得到消息偏移地址,大小,tagsCode


SelectMappedBufferResult selectResult = this.commitLog.getMessage(offsetPy, sizePy); 使用commitLog读取消息内容




                            
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然,我可以为您提供有关RocketMQ的一些笔记。这是一个开源的分布式消息中间件系统,由阿里巴巴集团开发和维护。RocketMQ具有高可用性、高吞吐量和可伸缩性,适用于构建实时数据处理、大规模消息系统和事件驱动架构等场景。 下面是一些关键点和要点: 1. 架构:RocketMQ采用了主题(Topic)和队列(Queue)的概念。主题是消息的逻辑分类,队列则是主题的物理分区。每个队列都有自己的消费者组来处理消息。 2. 消息模型:RocketMQ支持两种消息模型:发布/订阅模型和点对点模型。在发布/订阅模型中,消息发送到主题,然后订阅者从主题订阅消息。在点对点模型中,消息发送到队列,然后消费者从队列中消费消息。 3. 可靠性:RocketMQ提供了多种机制来确保消息的可靠性传输,包括同步发送、异步发送和定时发送。还支持消息顺序发送和顺序消费。 4. 高可用性:RocketMQ通过主从复制和Broker集群来实现高可用性。每个主题的队列都可以在多个Broker之间进行复制,以实现数据冗余和容错。 5. 扩展性:RocketMQ可以通过添加更多的Broker节点来扩展系统容量和吞吐量。还支持动态扩展和缩减Broker集群。 6. 消息过滤:RocketMQ支持基于Tag或SQL表达式的消息过滤,以便订阅者只接收感兴趣的消息。 这只是RocketMQ的一些基本信息,还有很多其他特性和概念,如事务消息、消息轨迹、延迟消息等。如果您对RocketMQ有进一步的疑问,请随时提问!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值