一.消息存储
commitLog:
commitLog文件是消息持久化的表现形式。
producer提交完消息后,broker会将消息首先持久化到commitLog中
。commitLog的写入是顺序写入的。每个commitLog文件大小默认1G
。每个消息占一个偏移量。当文件写满了,就写入下一个文件
(文件分片 保证一定程度上的顺序写)
ConsumerQueue:
消费队列,RocketMq是采取数据与索引分离的架构。想一想,如果consumer直接通过commitLog进行消费,那每次消费时都需要按照topic遍历commitLog文件是十分低效的。此时consumerQueue记录了每个消息在CommitLog文件中的一个偏移量。那么消费时可以通过队列中的索引进行直接定位。
结构上分为三个部分
1.commitLog消息的偏移量
2.消息的长度
3.tag的hashCode
其中
“1”是为了快速查找起始消息位置
“2”是为了读取整条消息
“3”是为了通过tag进行消息过滤。不过由于存储的是tag的hashcode而非本身。所以消费者最后还要自身进行tag字符的比对。
分类上。队列按topic进行分类,一个topic下可以有多个队列,每个队列都有一个Id。创建topic时可以设置多个队列。
使用时建议按照服务的节点进行分配队列,保证每个consumer都可以进行消费。读队列写队列尽量保持一致,因为读队列和写队列实际上不是物理隔离的。读队列是面向消费者的说法,写队列是面向producer的说法。
比如:
读队列 :4
写队列:3
消费者有4个
此时4个消费者被负载均衡到4个队列上,而生产者只会投递到指定的3个队列上,此时一个消费者就处于无消息消费的情况。
另一种情况:
如果生产环境下有8台节点,此时topic下的队列数量只设置了4个队列
则会有4个节点的consumer处于空闲状态。
IndexFile:
可以参考JDK的hashMap的结构。每个元素的结构:
1.Key Hash
2.Commit Log Offset
3.TimeStamp
4.Next Index Offset
“1” 是用来通过Message Key查询消息
“2” 消息的索引
“3” 记录的是消息storeTime