1、消息的生产
1.1 消息的生产过程
-
Producer发送消息之前,会从NameServer拉取topic的路由信息;
-
根据指定的Queue选择策略,从Queue列表中选出一个队列;
-
对消息做一些特殊处理,例如,消息本身超过4M,则会对其进行压缩;
-
向选择的Queue所在的Broker发出RPC请求,将消息发送到选择的Queue中。
1.2 Queue选择算法
对于无序消息,其Queue选择算法,也称为消息投递算法,常见的有两种:
轮询算法
这是默认选择的算法。该算法保证了每个Queue中可以均匀的获取到消息。
该算法存在一个问题:由于某些原因,在某些Broker上的Queue可能投递延迟较严重。从而导致Producer的缓存队列中出现较大的消息积压,影响消息的投递性能。
最小投递延迟算法
该算法会统计每次消息投递的时间延迟,然后根据统计出的结果将消息投递到时间延迟最小的Queue。
如果延迟相同,则采用轮询算法投递。该算法可以有效提升消息的投递性能。
该算法也存在一个问题:消息在Queue上的分配不均匀。投递延迟小的Queue其可能会存在大量的消息。而对该Queue的消费者压力会增大,降低消息的消费能力,可能会导致MQ中消息的堆积。
2、消息的存储
RocketMQ中的消息存储在本地文件系统中,可通过如下配置项进行配置。
storePathRootDir=/home/centos/Downloads/rocketmq-all-4.6.0-bin-release/data/143
storePathCommitLog=/home/centos/Downloads/rocketmq-all-4.6.0-bin-release/data/143/commitlog
storePathConsumerQueue=/home/centos/Downloads/rocketmq-all-4.6.0-bin-release/data/143/consumequeue
storePathIndex=/home/centos/Downloads/rocketmq-all-4.6.0-bin-release/data/143/index
storeCheckpoint=/home/centos/Downloads/rocketmq-all-4.6.0-bin-release/data/143/checkpoint
abortFile=/home/centos/Downloads/rocketmq-all-4.6.0-bin-release/data/143/abort
abort:该文件在Broker启动后会自动创建,正常关闭Broker,该文件会自动消失。若在没有启动Broker的情况下,发现这个文件是存在的,则说明之前Broker的关闭是非正常关闭。
checkpoint:其中存储着commitlog、consumequeue、index文件的最后刷盘时间戳
commitlog:其中存放着commitlog文件,而消息是写在commitlog文件中的
config:存放着Broker运行期间的一些配置数据
consumequeue:其中存放着consumequeue文件,队列就存放在这个目录中
index:其中存放着消息索引文件indexFile
lock:运行期间使用到的全局资源锁
2.1 commitlog
2.1.1 目录和文件
commitlog目录中的文件叫做mappedFile文件,用来存储broker的消息,每个mappedFile文件大小上限为1G。当一个mappedFile文件放满时,则会自动生成第二个文件继续存放消息。一个Broker中所有mappedFile文件的commitlog offset是连续的。
需要注意的是,一个Broker中仅包含一个commitlog目录,所有的mappedFile文件都是存放在该目录中。即无论当前Broker中存放着多少Topic的消息,这些消息都是被顺序写入到了mappedFile文件中。也就是说,这些消息在Broker中存放时并没有被按照Topic进行分类存放。
mappedFile文件是顺序读写的文件,所有其访问效率很高。
mappedFile文件名由20位十进制数构成,表示当前文件的第一条消息的起始位移偏移量。如第一个文件的文件名是20位0构成的,表示当前文件的offset从0开始。
2.1.2 消息单元
mappedFile文件内容由一个个的消息单元构成。每个消息单元中包含消息总长度MsgLen、消息的物理位置physicalOffset、消息体内容Body、消息体长度BodyLength、消息主题Topic、Topic长度
TopicLength、消息生产者BornHost、消息发送时间戳BornTimestamp、消息所在的队QueueId、消息在Queue中存储的偏移量QueueOffset等近20余项消息相关属性。
2.1.3 consumequeue
consumequeue文件是commitlog的索引文件,可以根据consumequeue定位到具体的消息。broker会为每个Topic在consumequeue中创建一个目录,目录名为Topic名称。在该Topic目录下,会再为每个该Topic的Queue建立一个目录,目录名为queueId,该目录下会包含若干个consumequeue文件。
consumequeue文件名也由20位数字构成,表示当前文件的第一个索引条目的起始位移偏移量。与
mappedFile文件名不同的是,其后续文件名是固定的。因为consumequeue文件大小是固定不变的。
每个consumequeue文件可以包含30w个索引条目,每个索引条目包含了三个消息重要属性:消息在mappedFile文件中的偏移量CommitLog Offset、消息长度、消息Tag的hashcode值。这三个属性占20个字节,所以每个consumequeue文件的大小是固定的30w * 20字节。
commitlog和consumequeue的关系示意图:
2.1.4 文件的读写
消息进入到Broker后的持久化过程:
①Broker根据queueId,获取到该消息对应索引条目要在consumequeue目录中的写入偏移量,即
QueueOffset;
②将queueId、queueOffset等数据,与消息一起封装为消息单元;
③将消息单元写入到commitlog;
④同时,形成消息索引条目并写到相应的consumequeue中。