【RocketMQ】源码系列研究-消息存储Broker(概要设计)

1.RocketMQ存储概要设计

    RocketMQ主要存储的文件包括Comitlog文件、ConsumeQueue文件、IndexFIle文件。RocketMQ将所有主题的消息存储在同一个文件中,确保消息发送时顺序写文件,尽最大的能力确保消息发送的高性能与吞吐量。但由于消息中间件一般是订阅机制,这样便给按照消息主题检索带来了极大的不便。为了提高效率,RocketMQ引入了ConsumeQueu消息队列文件,每个消息主题包含多个消息消费队列,每一个消息队列有一个消息文件。IndexFile索引文件,主要设计理念就是加速消息的检索性能,根据消息的属性快速从CommitLog文件中检索消息

     1.1: commitLog:消息存储文件,所有消息主题的消息都存储在CommitLog文件中。

     1.2     ConsumeQueue:消息消费队列,消息到达CommitLog文件后,将异步转发到消息消费队列,供消息消费者消费。

     1.3   IndexFile:消息索引文件,主要存储消息key与Offset的对应关系

     1.4 事物状态服务:存储每条消息的事物状态

     1.5 定时消息服务:每一个延迟级别对应一个消息消费队列,存储延迟队列的消息拉取进度。

 

2.功能描述

Broker是处理消息存储,转发等处理的服务器。

 1.Broker以group分开,每个group只允许一个master,若干个slave。

 2.只有master才能进行写入操作,slave不允许。

3.slave从master中同步数据,同步策略取决于master的配置,可以采用同步双写,异步复制两种。

4.客户端消费可以从master和slave消费。在默认情况下,消费者都从master消费,在master挂后,客户端由于从Name Server

中感知到Broker挂掉,就会从salve消费。

5.Broker向所有的Name Server节点建立长链接,注册Topic 信息。

 

3.消息发送存储流程

代码结构:

消息存储实现类:

在store模块中:

org.apache.rocketmq.store.DefaultMessageStore

这个类在存储模块中最重要的一个类:

下面列举一下核心属性和方法

1. MessageStoreConfig  messageStoreConfig :消息存储配置属性

2.CommitLog commitLog:CommitLog文件的存储实现类

3.ConcurrentMap<String /**topic */,ConcurrentMap<Integer/*queueId*/,Conssume-Queue>> consumeQueueTable:消息队列存储缓存表,按消息主体分组。

4.FlusConsumeQueueService flushConsumeQueueService :消息队列文件ConsumeQueue刷盘线程。

5. CleanCommitLogService cleanCommitLogService:清除CommitLog文件服务

6.CleanConsumeQueueService cleanConsumeQueueService :清除ConsumeQueue文件服务

7.IndexService indexService :索引文件实现类

8.AllocateMappedFileSErvice allocateMApppedFileService:MappedFile分配服务。

9.ReputMessageServie reputMessageService: CommitLog消息分发,根据CommitLog文件构建ConsumeQueue、IndexFile文件

10.HAService haService:存储HA机制

11.TransientStorePool transientStorePool: 消息堆内存缓存

12.MessageArrivingListener messagArrivingListener: 消息拉取长轮训模式消息达到监听器。

13.BrokerConfig brokerConfig :Broker配置属性。

14.StoreCheckpoint storeCheckPoint:文件刷盘监测点

15.LinkedList<CommitLogDispacher> dispatcherList:CommitLog文件转发请求。

消息存储追踪入口:

org.apache.rocketmq.store.DefaultMessageStore#putMessage

注意事项:

master节点允许写入,消息主体长度不能超过256个字符,消息属性成都不能超过65536个字符。

第二步:

如果消息的延迟级别大于0,将消息的原主题名称与原消息队列ID存入消息属性中,用延迟消息主体SCHEDULE_TOPIC,消息队列ID更新原消息的主题与队列,这个是并发消息消费重试关键的一步。

代码中有关于延迟时间的判断

第三步:

获取当前可以写入Commitlog文件,RocketMQ物理文件如下图:

 

 Commitlog文件存储目录为${ROCKETMQ_HOME}/store/commitlog目录,mac系统下面可以在用户根目录下面找store文件夹

每个文件默认1G,一个文件写满后,会再创建另外一个,以该文件中第一个偏移量为文件名称,偏移量小于20位用0补齐。如上图第一个文件的偏移量为0。MappedFileQueue可以看做是${ROCKETMQ_HOME}/store/commitlog文件夹,而MappedFile则对应该文件夹下一个个的文件。

第四步:

在写入Commitlog之前,先申请锁,消息存储到CommitLog文件是串行的。

第五步:

设置消息的存储时间,如果mappedFile为空,表明${ROCKETMQ_HOME}/store/commitlog目录下不存在任何文件,说明本次消息是第一次消息发送,用偏移量0创建第一个commit文件,。文件名:00000000000000000000

第六步:

将消息追加到MappedFile中。

第七步:

创建全局唯一消息ID,消息ID有16字节

 4字节IP:4字节端口号:8字节消息偏移量

第八步:

获取改消息在消息队列的偏移量。CommitLog中保存了当前所有消息队列的当前待写入偏移量。

第九步:

根据消息体的长度、主体的长度、属性的长度结合消息存储格式计算消息的总长度。

第十步:

如果消息长度+END_FILE_MIN_BLAK_LENGTH大于CommitLog文件的空闲空间,则返回AppendMessageStatus.END_OF_FILE,Broker会重新创建一个新的CommitLog文件来存储该消息。从这里可以看出,每个CommitLog文件最少会空闲8个字节,高4字节存储当前文件剩余空间,低4字节存储魔数:CommitLog.BLANK_MAGIC_CODE

十一步:

将消息内容存储到ByteBuffer中,然后创建AppendMessageResult。这一步只是将消息存储在MappedFile对应的内存映射Buffer中,并没有刷写到磁盘。

十二步:

更新消息队列逻辑偏移量

十三步:

处理完消息追加逻辑后将释放putMessageLock锁。

 

后续会分析:存储文件组织与内存映射机制

参考资料:《RocketMQ技术内幕》

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值