【RocketMQ】从 文件/数据结构 视角理解RocketMQ原理

1. NameServer 文件结构和数据结构

NameServer 是一个无状态的节点,用于维护 Broker 和 Topic 的路由信息,不涉及持久化文件,所有数据都存储在内存中。

•	RouteInfoManager:主要的数据结构,包含以下几部分:
	•	BrokerLiveTable:记录每个 Broker 的存活状态及其 IP、端口等信息,存活状态通过心跳机制维护。
	•	BrokerAddrTable:存储 Broker 名字对应的多个 Broker 节点(Master 和 Slave)的地址。
	•	TopicQueueTable:HashMap<String, List<QueueData>>,记录每个 Topic 对应的 QueueData,即每个 Topic 在不同 Broker 上的读写队列分布情况。

NameServer 的主要功能是提供路由信息,所有数据都是通过心跳和路由注册进行同步,定期向客户端提供最新的 Topic 和 Broker 信息。

注:因为没有持久化文件所有数据都存在内存中,所以节点重启之后无法从文件恢复、信息会丢失,所以才成为“无状态”
虽然NameServer是无状态,但是在集群环境下,多个NameServer节点的容灾能力还是可以的:

  • 启动之初,Broker们需要向所有的NameServer建立长链接并注册自身信息
  • 之后通过长链接,NameServer们不断从Broker更新注册信息
  • 也是通过长链接,Broker向NameServer们发动自身心跳
  • 同理生产、消费者需要配置所有的NameServer地址、之后走负载均衡来请求具体的NameServer获取Broker信息等

2. Broker 文件结构和数据结构

Broker 是 RocketMQ 的核心组件,负责消息的存储、转发及管理。它维护了多个核心文件结构和数据结构:

2.1 CommitLog

•	CommitLog 是 Broker 存储消息的主要文件,底层采用顺序写的文件系统。
•	文件结构:每个 CommitLog 文件大小是固定的(通常1GB),消息以顺序的方式写入文件中,多个文件形成一个链表。
•	功能:持久化所有的消息内容,支持高效的顺序写,以保证消息写入性能。支持消息的定期刷盘策略(同步或异步刷盘)。

同步或者异步刷盘是需要权衡的一件事情

  • 同步:避免了大部分的消息丢失场景、可靠性高,但是同时效率底、降低吞吐量
  • 异步:快速响应、提升吞吐量,但是存在消息丢失的风险

2.2 ConsumeQueue

•	ConsumeQueue 是针对每个 MessageQueue(消息队列)维护的消息索引文件,主要记录消息在 CommitLog 中的物理偏移量。
•	文件结构:每个 ConsumeQueue 文件的条目包含了消息的 CommitLog 偏移量、消息大小和消息 Tag 的哈希值。
•	功能:通过这个索引可以快速定位到消息在 CommitLog 中的位置,提升消息消费的效率。

所谓的读写队列,都是基于ConsumeQueue来的

2.3 IndexFile

•	IndexFile 是 Broker 提供的额外索引机制,基于哈希索引建立。每条消息可以通过唯一的 Key 和消息发送时间建立索引。
•	文件结构:存储 CommitLog 中消息的物理偏移量和 Key/时间的映射关系。
•	功能:提供消息的快速查询能力,允许通过 Key 或时间范围进行消息的精确查询。

2.4 TopicTable

•	TopicTable 是 Broker 中管理 Topic 元数据信息的核心数据结构,类似于一个 HashMap:
	HashMap<String, TopicConfig> TopicTable;
•	Key:Topic 名称。
•	Value:TopicConfig 对象,包含 Topic 的读写队列数量、权限等信息。
•	功能:负责记录每个 Topic 的队列分布情况及其权限控制。TopicTable 信息定期同步到 NameServer。

2.5 SubscriptionGroupTable

•	SubscriptionGroupTable:维护每个消费者组的订阅关系。它记录了每个消费者组可以消费哪些 Topic 以及消费权限等信息。

2.6 ConsumerOffset

•	ConsumerOffset:每个消费者组对 MessageQueue 的偏移量文件,用于记录消费者组当前消费到哪条消息,持久化存储在磁盘上。
•	文件结构:每个消费者组对应一个文件,记录它对每个 MessageQueue 的偏移量。
•	功能:消费者重启时可以从该偏移量继续消费消息,保证消费的可追溯性。

2.7 DelayQueue

•	DelayQueue:用于存储延时消息的消息队列。
•	文件结构:采用分层的时间轮机制,存储到期的延迟消息。5.0 版本后使用了基于时间轮的延时消息队列结构,提供更高效的延时消息支持。

DelayQueue严格来讲只是个概念上的队列、而不是个实际存在的文件或者结构,这玩意儿实际就是个时间轮(TimeWheel)结构、放在内存里,它重启之后会丢失,好在时间轮可以重建(依赖CommitLog中原始的消息信息)

3. 客户端(生产者/消费者)的文件结构和数据结构

客户端 包括生产者和消费者,通常没有涉及复杂的文件系统,但是也有一些关键的内存数据结构用于消费和生产消息。

3.1 Producer 端数据结构

•	MQClientInstance:生产者端的核心类,用于维护与 Broker 的网络连接及路由信息缓存。
•	TopicPublishInfo:记录每个 Topic 的路由信息,包括哪些 Broker 上有读写队列,生产者可以基于这个信息选择合适的队列发送消息。

3.2 Consumer 端数据结构

•	PullMessageService:负责从 Broker 拉取消息的服务。
•	RebalanceImpl:负责消费队列的负载均衡算法,确保不同消费者组之间均衡地消费 Topic 下的队列。

3.3 OffsetStore

•	OffsetStore:消费者端保存消息消费偏移量的组件,支持本地存储和远程存储两种模式。
	•	LocalFileOffsetStore:将偏移量保存在本地文件系统中,适用于本地模式的消费者。
	•	RemoteBrokerOffsetStore:将偏移量保存在 Broker 中,适用于集群模式下的消费者。
  • 集群模式下,offset文件放在broker中就行了,意思是你们一群人来消费,我具备公信力、所以我记录下你们消费到哪里了
  • 广播模式下,offset文件放到消费者侧,意思是你们各自消费,我总不能谁消费到哪里了我都记录,这样太麻烦我了,你们各自记住自己消费到哪里了

4. RocketMQ 的文件和数据结构总结

•	NameServer:无状态节点,核心结构是 RouteInfoManager,维护 Broker 和 Topic 路由信息。
•	Broker:
•	CommitLog:存储消息的文件,采用顺序写,支持高效持久化。
•	ConsumeQueue:索引文件,存储每个消息队列的物理偏移量,提升消费性能。
•	IndexFile:消息的哈希索引文件,支持通过 Key 和时间查询。
•	TopicTable:记录 Topic 的元数据信息,包括读写队列配置。
•	ConsumerOffset:记录消费者消费的偏移量。
•	DelayQueue:延时消息存储队列,采用时间轮机制。
•	客户端:
•	Producer:维护 Topic 的路由信息,用于选择合适的 Broker。
•	Consumer:通过 PullMessageService 拉取消息,使用 RebalanceImpl 进行负载均衡,依赖 OffsetStore 记录消费偏移量。

通过这些核心文件结构和数据结构,RocketMQ 实现了消息的高效存储、消费、索引以及负载均衡等功能,并通过 NameServer 保证系统的高可用性和可扩展性。

以上个人的一个总结,欢迎大家指正补充,转载标明出处谢谢;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值